Support document-relative and custom-frame page overlays
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 Apr 2014 21:41:28 +0000 (21:41 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 Apr 2014 21:41:28 +0000 (21:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=131560
<rdar://problem/16595556>

Reviewed by Simon Fraser.

Add "document-relative" overlays, which attach to (and scroll with) the document,
and can be given a frame rect within the document to avoid overallocation of backing store.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::didChangeScrollOffset):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::mainFrame):
(WebKit::WebPage::mainFrameView):
(WebKit::WebPage::didChangeScrollOffsetForFrame):
* WebProcess/WebPage/WebPage.h:
Let the PageOverlayController know *which* frame scrolled, instead of "any frame".

* WebProcess/WebPage/FindController.cpp:
(WebKit::FindController::updateFindUIAfterPageScroll):
Factor out shared code.

(WebKit::FindController::willMoveToWebPage):
(WebKit::FindController::drawRect):
We can use clearRect() instead of a transparency layer and fillRect().
I've looked through all the other overlay clients I know of and none of them
depend on having a transparency layer at the overlay level.

* WebProcess/WebPage/PageOverlay.cpp:
(WebKit::PageOverlay::create):
(WebKit::PageOverlay::PageOverlay):
(WebKit::PageOverlay::bounds):
(WebKit::PageOverlay::frame):
(WebKit::PageOverlay::setFrame):
(WebKit::PageOverlay::drawRect):
Add OverlayType, which allows creation of Document or View relative overlays.
All overlays up to this point are View relative, so we default to that.
Document-relative overlays scroll with the page instead of repainting as
the page scrolls. They can also be given an explicit frame, allowing them
to be smaller than the entire document.

* WebProcess/WebPage/PageOverlay.h:
(WebKit::PageOverlay::overlayType):
(WebKit::PageOverlay::webPage):
(WebKit::PageOverlay::client): Deleted.
* WebProcess/WebPage/PageOverlayController.cpp:
(WebKit::PageOverlayController::initialize):
(WebKit::PageOverlayController::installPageOverlay):
(WebKit::PageOverlayController::uninstallPageOverlay):
(WebKit::PageOverlayController::updateForceSynchronousScrollLayerPositionUpdates):
(WebKit::updateOverlayGeometry):
(WebKit::PageOverlayController::setPageOverlayNeedsDisplay):
(WebKit::PageOverlayController::didChangeViewSize):
(WebKit::PageOverlayController::didChangeDocumentSize):
(WebKit::PageOverlayController::didChangeDeviceScaleFactor):
(WebKit::PageOverlayController::didScrollFrame):
(WebKit::PageOverlayController::flushPageOverlayLayers):
(WebKit::PageOverlayController::didChangeOverlayFrame):
Keep two overlay root layers - one for view-relative
and one for document-relative overlays.
Don't force synchronous scrolling if we only have document-relative overlays.
Update the overlay's position as well as its size whenever necessary.
Update document-relative overlay geometry when the document size changes.
Only explicitly flush view-relative overlays; document-relative ones
are plugged into the WebCore layer tree and flushed along with the page.

* WebProcess/WebPage/PageOverlayController.h:
(WebKit::PageOverlayController::documentOverlayRootLayer):
(WebKit::PageOverlayController::viewOverlayRootLayer):
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::setRootCompositingLayer):
(WebKit::RemoteLayerTreeDrawingArea::mainFrameContentSizeChanged):
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::mainFrameContentSizeChanged):
(WebKit::TiledCoreAnimationDrawingArea::setRootCompositingLayer):
Let the PageOverlay controller know when the document size changes.
When we set up compositing, push the document overlay root layer
down into WebCore.

* WebCore.exp.in:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::RenderLayerCompositor):
(WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
(WebCore::RenderLayerCompositor::setDocumentOverlayRootLayer):
* rendering/RenderLayerCompositor.h:
Add the concept of a document overlay layer, which is plugged in as the
last child of the root content layer. Expose it to WebKit2.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@167152 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit2/WebProcess/WebPage/FindController.cpp
Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp
Source/WebKit2/WebProcess/WebPage/PageOverlay.h
Source/WebKit2/WebProcess/WebPage/PageOverlayController.cpp
Source/WebKit2/WebProcess/WebPage/PageOverlayController.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h
Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm
Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm

index 4f52439dc5e0d85dd876ac0045a36a4b90a8c04d..17e7671a03fb5e50f7ee77b1eb02f68710569fe4 100644 (file)
@@ -1,3 +1,20 @@
+2014-04-11  Tim Horton  <timothy_horton@apple.com>
+
+        Support document-relative and custom-frame page overlays
+        https://bugs.webkit.org/show_bug.cgi?id=131560
+        <rdar://problem/16595556>
+
+        Reviewed by Simon Fraser.
+
+        * WebCore.exp.in:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::RenderLayerCompositor):
+        (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
+        (WebCore::RenderLayerCompositor::setDocumentOverlayRootLayer):
+        * rendering/RenderLayerCompositor.h:
+        Add the concept of a document overlay layer, which is plugged in as the
+        last child of the root content layer. Expose it to WebKit2.
+
 2014-04-09  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Autocorrection causes ASSERT when replacing alternative string
index 39abc67af740194cc19fe06a3fad2b67dea53676..e8bc6356191ff554b69227966cb27bdede24eab6 100644 (file)
@@ -868,6 +868,7 @@ __ZN7WebCore21NetworkStorageSession25switchToNewTestingSessionEv
 __ZN7WebCore21NetworkStorageSession28createPrivateBrowsingSessionERKN3WTF6StringE
 __ZN7WebCore21PlatformKeyboardEvent24disambiguateKeyDownEventENS_13PlatformEvent4TypeEb
 __ZN7WebCore21RemoteCommandListener6createERNS_27RemoteCommandListenerClientE
+__ZN7WebCore21RenderLayerCompositor27setDocumentOverlayRootLayerEPNS_13GraphicsLayerE
 __ZN7WebCore21ResourceLoadScheduler20servePendingRequestsENS_20ResourceLoadPriorityE
 __ZN7WebCore21ResourceLoadScheduler20servePendingRequestsEPNS0_15HostInformationENS_20ResourceLoadPriorityE
 __ZN7WebCore21ResourceLoadScheduler21resumePendingRequestsEv
index aca3ddb751fea5c8c1c0fb5bbe8c3ea1a4422513..c846ecb782b3e7a5b3443b6cb5a9310d735f92e6 100644 (file)
@@ -255,6 +255,7 @@ RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
     , m_isTrackingRepaints(false)
     , m_layersWithTiledBackingCount(0)
     , m_rootLayerAttachment(RootLayerUnattached)
+    , m_documentOverlayRootLayer(nullptr)
     , m_layerFlushTimer(this, &RenderLayerCompositor::layerFlushTimerFired)
     , m_layerFlushThrottlingEnabled(page() && page()->progress().isMainLoadProgressing())
     , m_layerFlushThrottlingTemporarilyDisabledForInteraction(false)
@@ -1460,6 +1461,9 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer& layer, Vect
 
         childLayersOfEnclosingLayer.append(layerBacking->childForSuperlayers());
     }
+
+    if (m_documentOverlayRootLayer)
+        childLayersOfEnclosingLayer.append(m_documentOverlayRootLayer);
 }
 
 void RenderLayerCompositor::rebuildRegionCompositingLayerTree(RenderNamedFlowFragment* region, Vector<GraphicsLayer*>& childList, int depth)
@@ -3810,4 +3814,12 @@ void RenderLayerCompositor::paintRelatedMilestonesTimerFired(Timer<RenderLayerCo
     m_renderView.frameView().firePaintRelatedMilestonesIfNeeded();
 }
 
+void RenderLayerCompositor::setDocumentOverlayRootLayer(GraphicsLayer* documentOverlayRootLayer)
+{
+    if (m_documentOverlayRootLayer)
+        m_documentOverlayRootLayer->removeFromParent();
+    m_documentOverlayRootLayer = documentOverlayRootLayer;
+    scheduleCompositingLayerUpdate();
+}
+
 } // namespace WebCore
index 06a6ca368e4c607616eccf824b4fd292b754ae52..208206aad685ea17600fb732aae288791d1ab222 100644 (file)
@@ -304,6 +304,8 @@ public:
     void setRootExtendedBackgroundColor(const Color&);
     Color rootExtendedBackgroundColor() const { return m_rootExtendedBackgroundColor; }
 
+    void setDocumentOverlayRootLayer(GraphicsLayer*);
+
 private:
     class OverlapMap;
 
@@ -506,6 +508,8 @@ private:
     std::unique_ptr<GraphicsLayer> m_layerForFooter;
 #endif
 
+    GraphicsLayer* m_documentOverlayRootLayer;
+
     std::unique_ptr<GraphicsLayerUpdater> m_layerUpdater; // Updates tiled layer visible area periodically while animations are running.
 
     Timer<RenderLayerCompositor> m_layerFlushTimer;
index b7780646ddaa81fd9810c47841afebc70dc628a0..23936ef592ed3a684903da0f8a08829ff8f6b084 100644 (file)
@@ -1,3 +1,85 @@
+2014-04-11  Tim Horton  <timothy_horton@apple.com>
+
+        Support document-relative and custom-frame page overlays
+        https://bugs.webkit.org/show_bug.cgi?id=131560
+        <rdar://problem/16595556>
+
+        Reviewed by Simon Fraser.
+
+        Add "document-relative" overlays, which attach to (and scroll with) the document,
+        and can be given a frame rect within the document to avoid overallocation of backing store.
+
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::didChangeScrollOffset):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::mainFrame):
+        (WebKit::WebPage::mainFrameView):
+        (WebKit::WebPage::didChangeScrollOffsetForFrame):
+        * WebProcess/WebPage/WebPage.h:
+        Let the PageOverlayController know *which* frame scrolled, instead of "any frame".
+
+        * WebProcess/WebPage/FindController.cpp:
+        (WebKit::FindController::updateFindUIAfterPageScroll):
+        Factor out shared code.
+
+        (WebKit::FindController::willMoveToWebPage):
+        (WebKit::FindController::drawRect):
+        We can use clearRect() instead of a transparency layer and fillRect().
+        I've looked through all the other overlay clients I know of and none of them
+        depend on having a transparency layer at the overlay level.
+
+        * WebProcess/WebPage/PageOverlay.cpp:
+        (WebKit::PageOverlay::create):
+        (WebKit::PageOverlay::PageOverlay):
+        (WebKit::PageOverlay::bounds):
+        (WebKit::PageOverlay::frame):
+        (WebKit::PageOverlay::setFrame):
+        (WebKit::PageOverlay::drawRect):
+        Add OverlayType, which allows creation of Document or View relative overlays.
+        All overlays up to this point are View relative, so we default to that.
+        Document-relative overlays scroll with the page instead of repainting as
+        the page scrolls. They can also be given an explicit frame, allowing them
+        to be smaller than the entire document.
+
+        * WebProcess/WebPage/PageOverlay.h:
+        (WebKit::PageOverlay::overlayType):
+        (WebKit::PageOverlay::webPage):
+        (WebKit::PageOverlay::client): Deleted.
+        * WebProcess/WebPage/PageOverlayController.cpp:
+        (WebKit::PageOverlayController::initialize):
+        (WebKit::PageOverlayController::installPageOverlay):
+        (WebKit::PageOverlayController::uninstallPageOverlay):
+        (WebKit::PageOverlayController::updateForceSynchronousScrollLayerPositionUpdates):
+        (WebKit::updateOverlayGeometry):
+        (WebKit::PageOverlayController::setPageOverlayNeedsDisplay):
+        (WebKit::PageOverlayController::didChangeViewSize):
+        (WebKit::PageOverlayController::didChangeDocumentSize):
+        (WebKit::PageOverlayController::didChangeDeviceScaleFactor):
+        (WebKit::PageOverlayController::didScrollFrame):
+        (WebKit::PageOverlayController::flushPageOverlayLayers):
+        (WebKit::PageOverlayController::didChangeOverlayFrame):
+        Keep two overlay root layers - one for view-relative
+        and one for document-relative overlays.
+        Don't force synchronous scrolling if we only have document-relative overlays.
+        Update the overlay's position as well as its size whenever necessary.
+        Update document-relative overlay geometry when the document size changes.
+        Only explicitly flush view-relative overlays; document-relative ones
+        are plugged into the WebCore layer tree and flushed along with the page.
+
+        * WebProcess/WebPage/PageOverlayController.h:
+        (WebKit::PageOverlayController::documentOverlayRootLayer):
+        (WebKit::PageOverlayController::viewOverlayRootLayer):
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::setRootCompositingLayer):
+        (WebKit::RemoteLayerTreeDrawingArea::mainFrameContentSizeChanged):
+        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+        (WebKit::TiledCoreAnimationDrawingArea::mainFrameContentSizeChanged):
+        (WebKit::TiledCoreAnimationDrawingArea::setRootCompositingLayer):
+        Let the PageOverlay controller know when the document size changes.
+        When we set up compositing, push the document overlay root layer
+        down into WebCore.
+
 2014-04-11  Pratik Solanki  <psolanki@apple.com>
 
         [iOS WebKit2]: Share NSURLCache directory for webkit processes
index bccfae9b3a41ac2804e3e77cfddd42368c7f82fd..315de5e24e02bd3d6c33631143dd3104b32983e5 100644 (file)
@@ -1579,17 +1579,7 @@ void WebFrameLoaderClient::didChangeScrollOffset()
     if (!webPage)
         return;
 
-    webPage->didChangeScrollOffsetForAnyFrame();
-
-    if (!m_frame->isMainFrame())
-        return;
-
-    // If this is called when tearing down a FrameView, the WebCore::Frame's
-    // current FrameView will be null.
-    if (!m_frame->coreFrame()->view())
-        return;
-
-    webPage->updateMainFrameScrollOffsetPinning();
+    webPage->didChangeScrollOffsetForFrame(m_frame->coreFrame());
 }
 
 bool WebFrameLoaderClient::allowScript(bool enabledPerSettings)
index b06c6909dcb4bea9583fb8922c284009257edeb9..c6e6e96cc7d8141cf99516c119dfb1758ca82eb0 100644 (file)
@@ -162,9 +162,8 @@ void FindController::updateFindUIAfterPageScroll(bool found, const String& strin
             RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this);
             m_findPageOverlay = findPageOverlay.get();
             m_webPage->installPageOverlay(findPageOverlay.release(), PageOverlay::FadeMode::Fade);
-            m_findPageOverlay->setNeedsDisplay();
-        } else
-            m_findPageOverlay->setNeedsDisplay();
+        }
+        m_findPageOverlay->setNeedsDisplay();
     }
 }
 
@@ -394,7 +393,7 @@ static const float overlayBackgroundGreen = 0.1;
 static const float overlayBackgroundBlue = 0.1;
 static const float overlayBackgroundAlpha = 0.25;
 
-void FindController::drawRect(PageOverlay* /*pageOverlay*/, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
+void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
 {
     Color overlayBackgroundColor(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha);
 
@@ -413,16 +412,13 @@ void FindController::drawRect(PageOverlay* /*pageOverlay*/, GraphicsContext& gra
         for (size_t i = 0; i < rects.size(); ++i) {
             IntRect whiteFrameRect = rects[i];
             whiteFrameRect.inflate(1);
-
             graphicsContext.fillRect(whiteFrameRect);
         }
     }
 
-    graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB);
-
     // Clear out the holes.
     for (size_t i = 0; i < rects.size(); ++i)
-        graphicsContext.fillRect(rects[i]);
+        graphicsContext.clearRect(rects[i]);
 
     if (!m_isShowingFindIndicator)
         return;
index 19dea5e5148f5b8fe7dc2a6bba067e71d7c89390..e8480196dcd8fb0e6e8d222b8bce204c40f699dd 100644 (file)
@@ -42,12 +42,12 @@ namespace WebKit {
 static const double fadeAnimationDuration = 0.2;
 static const double fadeAnimationFrameRate = 30;
 
-PassRefPtr<PageOverlay> PageOverlay::create(Client* client)
+PassRefPtr<PageOverlay> PageOverlay::create(Client* client, OverlayType overlayType)
 {
-    return adoptRef(new PageOverlay(client));
+    return adoptRef(new PageOverlay(client, overlayType));
 }
 
-PageOverlay::PageOverlay(Client* client)
+PageOverlay::PageOverlay(Client* client, OverlayType overlayType)
     : m_client(client)
     , m_webPage(0)
     , m_fadeAnimationTimer(RunLoop::main(), this, &PageOverlay::fadeAnimationTimerFired)
@@ -55,6 +55,7 @@ PageOverlay::PageOverlay(Client* client)
     , m_fadeAnimationDuration(fadeAnimationDuration)
     , m_fadeAnimationType(NoAnimation)
     , m_fractionFadedIn(1.0)
+    , m_overlayType(overlayType)
 {
 }
 
@@ -64,18 +65,43 @@ PageOverlay::~PageOverlay()
 
 IntRect PageOverlay::bounds() const
 {
-    FrameView* frameView = m_webPage->corePage()->mainFrame().view();
+    if (!m_overrideFrame.isEmpty())
+        return IntRect(IntPoint(), m_overrideFrame.size());
 
-    int width = frameView->width();
-    int height = frameView->height();
+    FrameView* frameView = m_webPage->mainFrameView();
 
-    if (!ScrollbarTheme::theme()->usesOverlayScrollbars()) {
-        if (frameView->verticalScrollbar())
-            width -= frameView->verticalScrollbar()->width();
-        if (frameView->horizontalScrollbar())
-            height -= frameView->horizontalScrollbar()->height();
-    }    
-    return IntRect(0, 0, width, height);
+    switch (m_overlayType) {
+    case OverlayType::View: {
+        int width = frameView->width();
+        int height = frameView->height();
+
+        if (!ScrollbarTheme::theme()->usesOverlayScrollbars()) {
+            if (frameView->verticalScrollbar())
+                width -= frameView->verticalScrollbar()->width();
+            if (frameView->horizontalScrollbar())
+                height -= frameView->horizontalScrollbar()->height();
+        }
+        return IntRect(0, 0, width, height);
+    }
+    case OverlayType::Document:
+        return IntRect(IntPoint(), frameView->contentsSize());
+    };
+}
+
+IntRect PageOverlay::frame() const
+{
+    if (!m_overrideFrame.isEmpty())
+        return m_overrideFrame;
+
+    return bounds();
+}
+
+void PageOverlay::setFrame(IntRect frame)
+{
+    m_overrideFrame = frame;
+
+    if (m_webPage)
+        m_webPage->pageOverlayController().didChangeOverlayFrame(this);
 }
 
 void PageOverlay::setPage(WebPage* webPage)
@@ -108,12 +134,7 @@ void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirt
         return;
 
     GraphicsContextStateSaver stateSaver(graphicsContext);
-    graphicsContext.beginTransparencyLayer(1);
-    graphicsContext.setCompositeOperation(CompositeCopy);
-
     m_client->drawRect(this, graphicsContext, paintRect);
-
-    graphicsContext.endTransparencyLayer();
 }
     
 bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent)
index 61dba8b959a0171146a2db1572ffe8fe18b4cd1c..0a645afc883ae517b8b9f51c9a44c856c741e56e 100644 (file)
 
 #include "APIObject.h"
 #include "WKBase.h"
+#include <WebCore/IntRect.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RunLoop.h>
 
 namespace WebCore {
-    class GraphicsContext;
-    class IntPoint;
-    class IntRect;
+class GraphicsContext;
 }
 
 namespace WebKit {
@@ -59,7 +58,12 @@ public:
         virtual WKArrayRef copyAccessibilityAttributeNames(PageOverlay*, bool /* parameterizedNames */) { return 0; }
     };
 
-    static PassRefPtr<PageOverlay> create(Client*);
+    enum class OverlayType {
+        View, // Fixed to the view size; does not scale or scroll with the document, repaints on scroll.
+        Document, // Scales and scrolls with the document.
+    };
+
+    static PassRefPtr<PageOverlay> create(Client*, OverlayType = OverlayType::View);
     virtual ~PageOverlay();
 
     void setPage(WebPage*);
@@ -81,13 +85,17 @@ public:
     Client* client() const { return m_client; }
 
     enum class FadeMode { DoNotFade, Fade };
+
+    OverlayType overlayType() { return m_overlayType; }
+
+    WebCore::IntRect bounds() const;
+    WebCore::IntRect frame() const;
+    void setFrame(WebCore::IntRect);
     
 protected:
-    explicit PageOverlay(Client*);
+    explicit PageOverlay(Client*, OverlayType);
 
 private:
-    WebCore::IntRect bounds() const;
-
     void startFadeAnimation();
     void fadeAnimationTimerFired();
 
@@ -106,6 +114,9 @@ private:
 
     FadeAnimationType m_fadeAnimationType;
     float m_fractionFadedIn;
+
+    OverlayType m_overlayType;
+    WebCore::IntRect m_overrideFrame;
 };
 
 } // namespace WebKit
index 76b24b26487bbbfb24ef1f471477863538ec7359..725c0f92ac6ff3863bd87a5ec52600a4aaafd1a2 100644 (file)
 #include "DrawingArea.h"
 #include "PageOverlay.h"
 #include "WebPage.h"
+#include <WebCore/Frame.h>
 #include <WebCore/FrameView.h>
 #include <WebCore/GraphicsContext.h>
 #include <WebCore/GraphicsLayer.h>
+#include <WebCore/MainFrame.h>
 #include <WebCore/ScrollingCoordinator.h>
 #include <WebCore/Settings.h>
 #include <WebCore/TiledBacking.h>
@@ -47,17 +49,21 @@ PageOverlayController::PageOverlayController(WebPage* webPage)
 
 void PageOverlayController::initialize()
 {
-    ASSERT(!m_rootLayer);
+    ASSERT(!m_documentOverlayRootLayer);
+    ASSERT(!m_viewOverlayRootLayer);
 
-    m_rootLayer = GraphicsLayer::create(m_webPage->drawingArea()->graphicsLayerFactory(), this);
+    m_documentOverlayRootLayer = GraphicsLayer::create(m_webPage->drawingArea()->graphicsLayerFactory(), this);
+    m_viewOverlayRootLayer = GraphicsLayer::create(m_webPage->drawingArea()->graphicsLayerFactory(), this);
 #ifndef NDEBUG
-    m_rootLayer->setName("Page Overlay container");
+    m_documentOverlayRootLayer->setName("Page Overlay container (document-relative)");
+    m_viewOverlayRootLayer->setName("Page Overlay container (view-relative)");
 #endif
 }
 
 void PageOverlayController::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, PageOverlay::FadeMode fadeMode)
 {
-    ASSERT(m_rootLayer);
+    ASSERT(m_documentOverlayRootLayer);
+    ASSERT(m_viewOverlayRootLayer);
 
     RefPtr<PageOverlay> overlay = pageOverlay;
 
@@ -71,20 +77,26 @@ void PageOverlayController::installPageOverlay(PassRefPtr<PageOverlay> pageOverl
         overlay->startFadeInAnimation();
 
     std::unique_ptr<GraphicsLayer> layer = GraphicsLayer::create(m_webPage->drawingArea()->graphicsLayerFactory(), this);
+    layer->setAnchorPoint(FloatPoint3D());
+    layer->setPosition(overlay->frame().location());
 #ifndef NDEBUG
     layer->setName("Page Overlay content");
 #endif
 
     updateSettingsForLayer(layer.get());
-    m_rootLayer->addChild(layer.get());
-    m_overlayGraphicsLayers.set(overlay.get(), std::move(layer));
 
-#if ENABLE(ASYNC_SCROLLING)
-    if (Page* page = m_webPage->corePage()) {
-        if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
-            scrollingCoordinator->setForceSynchronousScrollLayerPositionUpdates(true);
+    switch (overlay->overlayType()) {
+    case PageOverlay::OverlayType::View:
+        m_viewOverlayRootLayer->addChild(layer.get());
+        break;
+    case PageOverlay::OverlayType::Document:
+        m_documentOverlayRootLayer->addChild(layer.get());
+        break;
     }
-#endif
+
+    m_overlayGraphicsLayers.set(overlay.get(), std::move(layer));
+
+    updateForceSynchronousScrollLayerPositionUpdates();
 }
 
 void PageOverlayController::uninstallPageOverlay(PageOverlay* overlay, PageOverlay::FadeMode fadeMode)
@@ -102,17 +114,36 @@ void PageOverlayController::uninstallPageOverlay(PageOverlay* overlay, PageOverl
     ASSERT(overlayIndex != notFound);
     m_pageOverlays.remove(overlayIndex);
 
-    if (!m_pageOverlays.isEmpty())
-        return;
+    updateForceSynchronousScrollLayerPositionUpdates();
+}
 
+void PageOverlayController::updateForceSynchronousScrollLayerPositionUpdates()
+{
 #if ENABLE(ASYNC_SCROLLING)
+    bool forceSynchronousScrollLayerPositionUpdates = false;
+
+    for (auto& overlay : m_pageOverlays) {
+        if (overlay->overlayType() == PageOverlay::OverlayType::View)
+            forceSynchronousScrollLayerPositionUpdates = true;
+    }
+
     if (Page* page = m_webPage->corePage()) {
         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
-            scrollingCoordinator->setForceSynchronousScrollLayerPositionUpdates(false);
+            scrollingCoordinator->setForceSynchronousScrollLayerPositionUpdates(forceSynchronousScrollLayerPositionUpdates);
     }
 #endif
 }
 
+static void updateOverlayGeometry(PageOverlay* overlay, GraphicsLayer* graphicsLayer)
+{
+    if (!graphicsLayer->drawsContent())
+        return;
+
+    graphicsLayer->setPosition(overlay->frame().location());
+    graphicsLayer->setSize(overlay->frame().size());
+    graphicsLayer->setNeedsDisplay();
+}
+
 void PageOverlayController::setPageOverlayNeedsDisplay(PageOverlay* overlay, const WebCore::IntRect& dirtyRect)
 {
     GraphicsLayer* graphicsLayer = m_overlayGraphicsLayers.get(overlay);
@@ -121,8 +152,9 @@ void PageOverlayController::setPageOverlayNeedsDisplay(PageOverlay* overlay, con
 
     if (!graphicsLayer->drawsContent()) {
         graphicsLayer->setDrawsContent(true);
-        graphicsLayer->setSize(m_webPage->size());
+        updateOverlayGeometry(overlay, graphicsLayer);
     }
+
     graphicsLayer->setNeedsDisplayInRect(dirtyRect);
 }
 
@@ -147,11 +179,17 @@ void PageOverlayController::clearPageOverlay(PageOverlay* overlay)
 
 void PageOverlayController::didChangeViewSize()
 {
-    for (auto& graphicsLayer : m_overlayGraphicsLayers.values()) {
-        if (!graphicsLayer->drawsContent())
-            continue;
-        graphicsLayer->setSize(m_webPage->size());
-        graphicsLayer->setNeedsDisplay();
+    for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
+        if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::View)
+            updateOverlayGeometry(overlayAndLayer.key, overlayAndLayer.value.get());
+    }
+}
+
+void PageOverlayController::didChangeDocumentSize()
+{
+    for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
+        if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::Document)
+            updateOverlayGeometry(overlayAndLayer.key, overlayAndLayer.value.get());
     }
 }
 
@@ -163,8 +201,11 @@ void PageOverlayController::didChangePreferences()
 
 void PageOverlayController::didChangeDeviceScaleFactor()
 {
-    m_rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
-    invalidateAllPageOverlayLayers();
+    m_documentOverlayRootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
+    m_viewOverlayRootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
+
+    for (auto& graphicsLayer : m_overlayGraphicsLayers.values())
+        graphicsLayer->setNeedsDisplay();
 }
 
 void PageOverlayController::didChangeExposedRect()
@@ -172,20 +213,17 @@ void PageOverlayController::didChangeExposedRect()
     m_webPage->drawingArea()->scheduleCompositingLayerFlush();
 }
 
-void PageOverlayController::didScrollAnyFrame()
+void PageOverlayController::didScrollFrame(Frame* frame)
 {
-    invalidateAllPageOverlayLayers();
-}
-
-void PageOverlayController::invalidateAllPageOverlayLayers()
-{
-    for (auto& graphicsLayer : m_overlayGraphicsLayers.values())
-        graphicsLayer->setNeedsDisplay();
+    for (auto& overlayAndLayer : m_overlayGraphicsLayers) {
+        if (overlayAndLayer.key->overlayType() == PageOverlay::OverlayType::View || !frame->isMainFrame())
+            overlayAndLayer.value->setNeedsDisplay();
+    }
 }
 
 void PageOverlayController::flushPageOverlayLayers(FloatRect visibleRect)
 {
-    m_rootLayer->flushCompositingState(visibleRect);
+    m_viewOverlayRootLayer->flushCompositingState(visibleRect);
 }
 
 void PageOverlayController::updateSettingsForLayer(GraphicsLayer* layer)
@@ -259,4 +297,16 @@ void PageOverlayController::notifyFlushRequired(const WebCore::GraphicsLayer*)
     m_webPage->drawingArea()->scheduleCompositingLayerFlush();
 }
 
+void PageOverlayController::didChangeOverlayFrame(PageOverlay* overlay)
+{
+    ASSERT(m_pageOverlays.contains(overlay));
+
+    GraphicsLayer* graphicsLayer = m_overlayGraphicsLayers.get(overlay);
+
+    if (!graphicsLayer->drawsContent())
+        return;
+
+    updateOverlayGeometry(overlay, graphicsLayer);
+}
+
 } // namespace WebKit
index 74302e7dcd898b3a3a9e179142260c5fa223cfce..0a8776f6970c6119bdde4fec08a7be1feda56c04 100644 (file)
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
+namespace WebCore {
+class Frame;
+}
+
 namespace WebKit {
 
 class WebMouseEvent;
@@ -44,7 +48,8 @@ public:
 
     void initialize();
 
-    WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); }
+    WebCore::GraphicsLayer* documentOverlayRootLayer() const { return m_documentOverlayRootLayer.get(); }
+    WebCore::GraphicsLayer* viewOverlayRootLayer() const { return m_viewOverlayRootLayer.get(); }
 
     void installPageOverlay(PassRefPtr<PageOverlay>, PageOverlay::FadeMode);
     void uninstallPageOverlay(PageOverlay*, PageOverlay::FadeMode);
@@ -54,10 +59,12 @@ public:
     void clearPageOverlay(PageOverlay*);
 
     void didChangeViewSize();
+    void didChangeDocumentSize();
     void didChangePreferences();
     void didChangeDeviceScaleFactor();
     void didChangeExposedRect();
-    void didScrollAnyFrame();
+    void didScrollFrame(WebCore::Frame*);
+    void didChangeOverlayFrame(PageOverlay*);
 
     void flushPageOverlayLayers(WebCore::FloatRect);
 
@@ -69,7 +76,7 @@ public:
 
 private:
     void updateSettingsForLayer(WebCore::GraphicsLayer*);
-    void invalidateAllPageOverlayLayers();
+    void updateForceSynchronousScrollLayerPositionUpdates();
 
     // WebCore::GraphicsLayerClient
     virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double) override { }
@@ -78,7 +85,8 @@ private:
     virtual float deviceScaleFactor() const override;
     virtual void didCommitChangesForLayer(const WebCore::GraphicsLayer*) const override { }
 
-    std::unique_ptr<WebCore::GraphicsLayer> m_rootLayer;
+    std::unique_ptr<WebCore::GraphicsLayer> m_documentOverlayRootLayer;
+    std::unique_ptr<WebCore::GraphicsLayer> m_viewOverlayRootLayer;
     HashMap<PageOverlay*, std::unique_ptr<WebCore::GraphicsLayer>> m_overlayGraphicsLayers;
     Vector<RefPtr<PageOverlay>> m_pageOverlays;
     WebPage* m_webPage;
index d45834ebd9ed2c0c2f9b3c8e138c993f2611e568..36467c3ac647ab9c2b784c6ddfc5a5c0272918eb 100644 (file)
@@ -3817,7 +3817,7 @@ void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
 
 Frame* WebPage::mainFrame() const
 {
-    return m_page ? &m_page->mainFrame() : 0;
+    return m_page ? &m_page->mainFrame() : nullptr;
 }
 
 FrameView* WebPage::mainFrameView() const
@@ -3825,7 +3825,7 @@ FrameView* WebPage::mainFrameView() const
     if (Frame* frame = mainFrame())
         return frame->view();
     
-    return 0;
+    return nullptr;
 }
 
 void WebPage::setScrollingPerformanceLoggingEnabled(bool enabled)
@@ -4506,9 +4506,19 @@ TelephoneNumberOverlayController& WebPage::telephoneNumberOverlayController()
 }
 #endif
 
-void WebPage::didChangeScrollOffsetForAnyFrame()
+void WebPage::didChangeScrollOffsetForFrame(Frame* frame)
 {
-    m_pageOverlayController.didScrollAnyFrame();
+    m_pageOverlayController.didScrollFrame(frame);
+
+    if (!frame->isMainFrame())
+        return;
+
+    // If this is called when tearing down a FrameView, the WebCore::Frame's
+    // current FrameView will be null.
+    if (!frame->view())
+        return;
+
+    updateMainFrameScrollOffsetPinning();
 }
 
 } // namespace WebKit
index c9d64048da1d201258fcd7aa8659dce3dee0ec3c..3df84f76c516a520977d4014cd20f131f6da7717 100644 (file)
@@ -780,7 +780,7 @@ public:
     void handleTelephoneNumberClick(const String& number, const WebCore::IntPoint&);
 #endif
 
-    void didChangeScrollOffsetForAnyFrame();
+    void didChangeScrollOffsetForFrame(WebCore::Frame*);
 
 private:
     WebPage(uint64_t pageID, const WebPageCreationParameters&);
index f1895f019e05d63d8b3f416385fa512ae25c7753..e0d0a377aa85c7d7cad8665ac68f5ee79856a41f 100644 (file)
@@ -81,6 +81,8 @@ private:
     virtual void setDeviceScaleFactor(float) override;
 #endif
 
+    virtual void mainFrameContentSizeChanged(const WebCore::IntSize&) override;
+
     void updateScrolledExposedRect();
 
     void layerFlushTimerFired(WebCore::Timer<RemoteLayerTreeDrawingArea>*);
index 320dc607898bd3645e69dbbca8cab51b6e4b839a..1adc5a5e3c1a51ef606d5f431f1bc63ba5cb87ea 100644 (file)
@@ -38,6 +38,8 @@
 #import <WebCore/Frame.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/MainFrame.h>
+#import <WebCore/RenderLayerCompositor.h>
+#import <WebCore/RenderView.h>
 #import <WebCore/Settings.h>
 #import <WebCore/TiledBacking.h>
 
@@ -89,9 +91,11 @@ void RemoteLayerTreeDrawingArea::setRootCompositingLayer(GraphicsLayer* rootLaye
     Vector<GraphicsLayer *> children;
     if (rootLayer) {
         children.append(rootLayer);
-        children.append(m_webPage->pageOverlayController().rootLayer());
+        children.append(m_webPage->pageOverlayController().viewOverlayRootLayer());
     }
     m_rootLayer->setChildren(children);
+
+    m_webPage->mainFrameView()->renderView()->compositor().setDocumentOverlayRootLayer(m_webPage->pageOverlayController().documentOverlayRootLayer());
 }
 
 void RemoteLayerTreeDrawingArea::updateGeometry(const IntSize& viewSize, const IntSize& layerPosition)
@@ -293,4 +297,9 @@ void RemoteLayerTreeDrawingArea::didUpdate()
     }
 }
 
+void RemoteLayerTreeDrawingArea::mainFrameContentSizeChanged(const IntSize&)
+{
+    m_webPage->pageOverlayController().didChangeDocumentSize();
+}
+
 } // namespace WebKit
index c376e3bcb3cc3c8b53b2f4321ac78f27d701ded8..d06d41353caeca67f08aca017fcff4e6c46cc47c 100644 (file)
@@ -201,6 +201,8 @@ void TiledCoreAnimationDrawingArea::updatePreferences(const WebPreferencesStore&
 
 void TiledCoreAnimationDrawingArea::mainFrameContentSizeChanged(const IntSize&)
 {
+    m_webPage->pageOverlayController().didChangeDocumentSize();
+
     if (!m_webPage->minimumLayoutSize().width())
         return;
 
@@ -445,7 +447,9 @@ void TiledCoreAnimationDrawingArea::setRootCompositingLayer(CALayer *layer)
     [CATransaction begin];
     [CATransaction setDisableActions:YES];
 
-    [m_hostingLayer setSublayers:layer ? @[ layer, m_webPage->pageOverlayController().rootLayer()->platformLayer() ] : @[ ]];
+    [m_hostingLayer setSublayers:layer ? @[ layer, m_webPage->pageOverlayController().viewOverlayRootLayer()->platformLayer() ] : @[ ]];
+
+    m_webPage->mainFrameView()->renderView()->compositor().setDocumentOverlayRootLayer(m_webPage->pageOverlayController().documentOverlayRootLayer());
 
     bool hadRootLayer = !!m_rootLayer;
     m_rootLayer = layer;