Initial support for fixed position elements in Qt WebKit2
authoryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Apr 2012 23:40:51 +0000 (23:40 +0000)
committeryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Apr 2012 23:40:51 +0000 (23:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=81786

Reviewed by Noam Rosenthal.

.:

* ManualTests/fixed-position.html: Added.

Source/WebCore:

When the setting acceleratedCompositingForFixedPositionEnabled is true, we update
the position of fixed layers, and send updates to the UI process as we scroll.
Before painting, TextureMapperLayer receives a delta of the scroll positions between the UI
and the web processes, and adjusts its transform position accordingly.

* page/FrameView.cpp:
(WebCore::FrameView::setFixedVisibleContentRect):
* platform/graphics/texmap/TextureMapperLayer.cpp:
(WebCore::TextureMapperLayer::setScrollPositionDelta):
(WebCore):
* platform/graphics/texmap/TextureMapperLayer.h:
(TextureMapperLayer):

Source/WebKit2:

Turn on the flag acceleratedCompositingForFixedPositionEnabled when using fixed layout.
As we scroll, we keep track of the delta in scroll position between the UI and web processes,
and adjust the position of all the fixed layers by that delta.
When WebLayerTreeRenderer receives a new scroll position from the web process, it keeps it as pending,
and commit the new scroll position in flushLayerChanges.
This patch does not address scrolling overshoot and it does not fix the wrong positioning
that occurs when we zoom. These issues will be addressed in future patches.

* Shared/WebLayerTreeInfo.h:
* UIProcess/API/qt/qquickwebpage.cpp:
(QQuickWebPagePrivate::updateSize):
* UIProcess/LayerTreeHostProxy.cpp:
(WebKit::LayerTreeHostProxy::setContentsSize):
(WebKit):
(WebKit::LayerTreeHostProxy::renderNextFrame):
(WebKit::LayerTreeHostProxy::didChangeScrollPosition):
* UIProcess/LayerTreeHostProxy.h:
(LayerTreeHostProxy):
* UIProcess/LayerTreeHostProxy.messages.in:
* UIProcess/WebLayerTreeRenderer.cpp:
(WebKit::boundedScrollPosition):
(WebKit):
(WebKit::WebLayerTreeRenderer::paintToCurrentGLContext):
(WebKit::WebLayerTreeRenderer::setContentsSize):
(WebKit::WebLayerTreeRenderer::adjustPositionForFixedLayers):
(WebKit::WebLayerTreeRenderer::didChangeScrollPosition):
(WebKit::WebLayerTreeRenderer::syncLayerParameters):
(WebKit::WebLayerTreeRenderer::deleteLayer):
(WebKit::WebLayerTreeRenderer::flushLayerChanges):
* UIProcess/WebLayerTreeRenderer.h:
(WebLayerTreeRenderer):
* WebProcess/WebCoreSupport/WebGraphicsLayer.cpp:
(WebCore::WebGraphicsLayer::WebGraphicsLayer):
(WebCore::WebGraphicsLayer::syncCompositingState):
(WebCore::WebGraphicsLayer::syncCompositingStateForThisLayerOnly):
* WebProcess/WebCoreSupport/WebGraphicsLayer.h:
(WebGraphicsLayerClient):
(WebCore::WebGraphicsLayer::fixedToViewport):
(WebCore::WebGraphicsLayer::setFixedToViewport):
(WebGraphicsLayer):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setResizesToContentsUsingLayoutSize):
* WebProcess/WebPage/qt/LayerTreeHostQt.cpp:
(WebKit::LayerTreeHostQt::LayerTreeHostQt):
(WebKit::LayerTreeHostQt::didSyncCompositingStateForLayer):
(WebKit::updateOffsetFromViewportForSelf):
(WebKit):
(WebKit::updateOffsetFromViewportForLayer):
(WebKit::LayerTreeHostQt::syncFixedLayers):
(WebKit::LayerTreeHostQt::setVisibleContentsRect):
* WebProcess/WebPage/qt/LayerTreeHostQt.h:
(LayerTreeHostQt):

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

19 files changed:
ChangeLog
ManualTests/fixed-position.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebLayerTreeInfo.h
Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp
Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp
Source/WebKit2/UIProcess/LayerTreeHostProxy.h
Source/WebKit2/UIProcess/LayerTreeHostProxy.messages.in
Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp
Source/WebKit2/UIProcess/WebLayerTreeRenderer.h
Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp
Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h

index 919723d..eb3cd51 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-04-10  Yael Aharon  <yael.aharon@nokia.com>
+
+        Initial support for fixed position elements in Qt WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=81786
+
+        Reviewed by Noam Rosenthal.
+
+        * ManualTests/fixed-position.html: Added.
+
 2012-04-10  Raphael Kubo da Costa  <rakuco@webkit.org>
 
         [CMake] Do not pass -P to the preprocessor when running make_names.pl.
diff --git a/ManualTests/fixed-position.html b/ManualTests/fixed-position.html
new file mode 100644 (file)
index 0000000..a4d3e22
--- /dev/null
@@ -0,0 +1,92 @@
+<html><head>
+
+<meta content="text/html; charset=windows-1251" http-equiv="Content-Type">
+<style>
+.d1{position:fixed;top:50%;right:50%;z-index:2;overflow:hidden;}
+.d2{position:fixed;bottom:5em;left:50;z-index:2;overflow:hidden;}
+.o {background:green;height:40px;width:200px;}
+.t { width:2000px; height:198px;background-color: lightgray; border: 1px solid blue;}
+body { margin: 0px; }
+</style>
+<script>
+function remove_fixed()
+{
+  document.getElementById("d1").style.position = "static";
+}
+
+function change_fixed()
+{
+  document.getElementById("d2").style.bottom = "10em";
+}
+
+</script>
+</head>
+<body class="Gradient">
+<div class="d1" id="d1"><div class="o">This is a test</div></div>
+<div class="d2" id="d2"><div class="o">This is a test</div></div>
+<div class="t" onclick="remove_fixed();">
+000
+</div>
+<div class="t">
+200<br>
+<button onclick="remove_fixed();">remove fixed</button>
+</div>
+<div class="t">
+400<br>
+<button onclick="change_fixed();">change fixed</button>
+</div>
+<div class="t">
+600
+</div>
+<div class="t">
+800
+</div>
+<div class="t">
+1000
+</div>
+<div class="t">
+1200
+</div>
+<div class="t">
+1400
+</div>
+<div class="t">
+1600
+</div>
+<div class="t">
+1800
+</div>
+<div class="t">
+2000
+</div>
+<div class="t">
+2200
+</div>
+<div class="t">
+2400
+</div>
+<div class="t">
+2600
+</div>
+<div class="t">
+2800
+</div>
+<div class="t">
+3000
+</div>
+<div class="t">
+3200
+</div>
+<div class="t">
+3400
+</div>
+<div class="t">
+3600
+</div>
+<div class="t">
+3800
+</div>
+<div class="t">
+4000
+</div>
+</body></html>
index 3b3e9de..7f7547a 100644 (file)
@@ -1,3 +1,23 @@
+2012-04-10  Yael Aharon  <yael.aharon@nokia.com>
+
+        Initial support for fixed position elements in Qt WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=81786
+
+        Reviewed by Noam Rosenthal.
+
+        When the setting acceleratedCompositingForFixedPositionEnabled is true, we update
+        the position of fixed layers, and send updates to the UI process as we scroll.
+        Before painting, TextureMapperLayer receives a delta of the scroll positions between the UI 
+        and the web processes, and adjusts its transform position accordingly.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setFixedVisibleContentRect):
+        * platform/graphics/texmap/TextureMapperLayer.cpp:
+        (WebCore::TextureMapperLayer::setScrollPositionDelta):
+        (WebCore):
+        * platform/graphics/texmap/TextureMapperLayer.h:
+        (TextureMapperLayer):
+
 2012-04-10  Peter Rybin  <peter.rybin@gmail.com>
 
         Web Inspector: CodeGeneratorInspector.py: do not expose raw methods from generated types
index 13c5e28..c1b7005 100644 (file)
@@ -1702,8 +1702,11 @@ void FrameView::setFixedVisibleContentRect(const IntRect& visibleContentRect)
 {
     IntSize offset = scrollOffset();
     ScrollView::setFixedVisibleContentRect(visibleContentRect);
-    if (offset != scrollOffset())
+    if (offset != scrollOffset()) {
+        if (m_frame->page()->settings()->acceleratedCompositingForFixedPositionEnabled())
+            updateFixedElementsAfterScrolling();
         scrollPositionChanged();
+    }
     frame()->loader()->client()->didChangeScrollOffset();
 }
 
index db59807..5775cdb 100644 (file)
@@ -511,5 +511,14 @@ void TextureMapperLayer::syncCompositingState(GraphicsLayerTextureMapper* graphi
     }
 }
 
+void TextureMapperLayer::setScrollPositionDelta(const IntPoint& delta)
+{
+    // delta is the difference between the scroll offset in the ui process and the scroll offset
+    // in the web process. We add this delta to the position of fixed layers, to make
+    // sure that they do not move while scrolling.
+    m_scrollPositionDelta = delta;
+    m_transform.setPosition(m_state.pos + m_scrollPositionDelta);
+}
+
 }
 #endif
index e10d5a7..ed3b1af 100644 (file)
@@ -126,6 +126,8 @@ public:
     PassRefPtr<TextureMapperBackingStore> backingStore() { return m_backingStore; }
     void clearBackingStoresRecursive();
 
+    void setScrollPositionDelta(const IntPoint&);
+
 private:
     TextureMapperLayer* rootLayer();
     void computeTransformsRecursive();
@@ -217,6 +219,7 @@ private:
     State m_state;
     TextureMapper* m_textureMapper;
     TextureMapperAnimations m_animations;
+    IntPoint m_scrollPositionDelta;
 };
 
 
index 3188da7..97da4d9 100644 (file)
@@ -1,3 +1,63 @@
+2012-04-10  Yael Aharon  <yael.aharon@nokia.com>
+
+        Initial support for fixed position elements in Qt WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=81786
+
+        Reviewed by Noam Rosenthal.
+
+        Turn on the flag acceleratedCompositingForFixedPositionEnabled when using fixed layout.
+        As we scroll, we keep track of the delta in scroll position between the UI and web processes,
+        and adjust the position of all the fixed layers by that delta.
+        When WebLayerTreeRenderer receives a new scroll position from the web process, it keeps it as pending,
+        and commit the new scroll position in flushLayerChanges.
+        This patch does not address scrolling overshoot and it does not fix the wrong positioning
+        that occurs when we zoom. These issues will be addressed in future patches.
+
+        * Shared/WebLayerTreeInfo.h:
+        * UIProcess/API/qt/qquickwebpage.cpp:
+        (QQuickWebPagePrivate::updateSize):
+        * UIProcess/LayerTreeHostProxy.cpp:
+        (WebKit::LayerTreeHostProxy::setContentsSize):
+        (WebKit):
+        (WebKit::LayerTreeHostProxy::renderNextFrame):
+        (WebKit::LayerTreeHostProxy::didChangeScrollPosition):
+        * UIProcess/LayerTreeHostProxy.h:
+        (LayerTreeHostProxy):
+        * UIProcess/LayerTreeHostProxy.messages.in:
+        * UIProcess/WebLayerTreeRenderer.cpp:
+        (WebKit::boundedScrollPosition):
+        (WebKit):
+        (WebKit::WebLayerTreeRenderer::paintToCurrentGLContext):
+        (WebKit::WebLayerTreeRenderer::setContentsSize):
+        (WebKit::WebLayerTreeRenderer::adjustPositionForFixedLayers):
+        (WebKit::WebLayerTreeRenderer::didChangeScrollPosition):
+        (WebKit::WebLayerTreeRenderer::syncLayerParameters):
+        (WebKit::WebLayerTreeRenderer::deleteLayer):
+        (WebKit::WebLayerTreeRenderer::flushLayerChanges):
+        * UIProcess/WebLayerTreeRenderer.h:
+        (WebLayerTreeRenderer):
+        * WebProcess/WebCoreSupport/WebGraphicsLayer.cpp:
+        (WebCore::WebGraphicsLayer::WebGraphicsLayer):
+        (WebCore::WebGraphicsLayer::syncCompositingState):
+        (WebCore::WebGraphicsLayer::syncCompositingStateForThisLayerOnly):
+        * WebProcess/WebCoreSupport/WebGraphicsLayer.h:
+        (WebGraphicsLayerClient):
+        (WebCore::WebGraphicsLayer::fixedToViewport):
+        (WebCore::WebGraphicsLayer::setFixedToViewport):
+        (WebGraphicsLayer):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::setResizesToContentsUsingLayoutSize):
+        * WebProcess/WebPage/qt/LayerTreeHostQt.cpp:
+        (WebKit::LayerTreeHostQt::LayerTreeHostQt):
+        (WebKit::LayerTreeHostQt::didSyncCompositingStateForLayer):
+        (WebKit::updateOffsetFromViewportForSelf):
+        (WebKit):
+        (WebKit::updateOffsetFromViewportForLayer):
+        (WebKit::LayerTreeHostQt::syncFixedLayers):
+        (WebKit::LayerTreeHostQt::setVisibleContentsRect):
+        * WebProcess/WebPage/qt/LayerTreeHostQt.h:
+        (LayerTreeHostQt):
+
 2012-04-10  Anders Carlsson  <andersca@apple.com>
 
         Fix fast/images/exif-orientation.html WebKitTestRunner failure
index f9a2de1..7600633 100644 (file)
@@ -65,6 +65,7 @@ struct WebLayerInfo {
             bool masksToBounds : 1;
             bool preserves3D : 1;
             bool isRootLayer: 1;
+            bool fixedToViewport : 1;
         };
         unsigned int flags;
     };
index d3214ac..3060fbd 100644 (file)
@@ -139,6 +139,9 @@ void QQuickWebPagePrivate::updateSize()
     QSizeF scaledSize = contentsSize * contentsScale;
     q->setSize(scaledSize);
     viewportItem->updateContentsSize(scaledSize);
+    DrawingAreaProxy* drawingArea = webPageProxy->drawingArea();
+    if (drawingArea && drawingArea->layerTreeHostProxy())
+        drawingArea->layerTreeHostProxy()->setContentsSize(WebCore::FloatSize(contentsSize.width(), contentsSize.height()));
 }
 
 QQuickWebPagePrivate::~QQuickWebPagePrivate()
index 31b60e5..5446a7b 100644 (file)
@@ -122,6 +122,11 @@ void LayerTreeHostProxy::destroyDirectlyCompositedImage(int64_t key)
     dispatchUpdate(bind(&WebLayerTreeRenderer::destroyImage, m_renderer.get(), key));
 }
 
+void LayerTreeHostProxy::setContentsSize(const FloatSize& contentsSize)
+{
+    m_renderer->setContentsSize(contentsSize);
+}
+
 void LayerTreeHostProxy::setVisibleContentsRect(const IntRect& rect, float scale, const FloatPoint& trajectoryVector)
 {
     m_renderer->setVisibleContentsRect(rect, scale);
@@ -133,6 +138,11 @@ void LayerTreeHostProxy::renderNextFrame()
     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID());
 }
 
+void LayerTreeHostProxy::didChangeScrollPosition(const IntPoint& position)
+{
+    dispatchUpdate(bind(&WebLayerTreeRenderer::didChangeScrollPosition, m_renderer.get(), position));
+}
+
 void LayerTreeHostProxy::purgeBackingStores()
 {
     m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID());
index 6c163c8..1554a33 100644 (file)
@@ -56,6 +56,7 @@ public:
     void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float opacity, const WebCore::FloatRect& clip);
     void paintToGraphicsContext(BackingStore::PlatformGraphicsContext);
     void purgeGLResources();
+    void setContentsSize(const WebCore::FloatSize&);
     void setVisibleContentsRect(const WebCore::IntRect&, float scale, const WebCore::FloatPoint& trajectory);
     void didRenderFrame();
     void createTileForLayer(int layerID, int tileID, const WebCore::IntRect&, const SurfaceUpdateInfo&);
@@ -66,6 +67,7 @@ public:
     void didReceiveLayerTreeHostProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
     void updateViewport();
     void renderNextFrame();
+    void didChangeScrollPosition(const WebCore::IntPoint& position);
     void purgeBackingStores();
     WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); }
 
index 28bbad1..47a1ee3 100644 (file)
@@ -29,5 +29,6 @@ messages -> LayerTreeHostProxy {
     CreateDirectlyCompositedImage(int64_t key, WebKit::ShareableBitmap::Handle handle)
     DestroyDirectlyCompositedImage(int64_t key)
     DidRenderFrame()
+    DidChangeScrollPosition(WebCore::IntPoint position)
 }
 #endif
index abbd3aa..24c0ba1 100644 (file)
@@ -73,6 +73,17 @@ void WebLayerTreeRenderer::callOnMainTread(const Function<void()>& function)
         MainThreadGuardedInvoker<WebLayerTreeRenderer>::call(this, function);
 }
 
+static IntPoint boundedScrollPosition(const IntPoint& scrollPosition, const IntRect& visibleContentRect, const FloatSize& contentSize)
+{
+    IntSize size(contentSize.width(), contentSize.height());
+    int scrollPositionX = std::max(scrollPosition.x(), 0);
+    scrollPositionX = std::min(scrollPositionX, size.width() - visibleContentRect.width());
+
+    int scrollPositionY = std::max(scrollPosition.y(), 0);
+    scrollPositionY = std::min(scrollPositionY, size.height() - visibleContentRect.height());
+    return IntPoint(scrollPositionX, scrollPositionY);
+}
+
 WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeHostProxy* layerTreeHostProxy)
     : m_layerTreeHostProxy(layerTreeHostProxy)
     , m_rootLayerID(0)
@@ -98,6 +109,7 @@ void WebLayerTreeRenderer::paintToCurrentGLContext(const TransformationMatrix& m
     ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode);
 
     syncRemoteContent();
+    adjustPositionForFixedLayers();
     GraphicsLayer* currentRootLayer = rootLayer();
     if (!currentRootLayer)
         return;
@@ -143,6 +155,11 @@ void WebLayerTreeRenderer::paintToGraphicsContext(QPainter* painter)
     m_textureMapper->setGraphicsContext(0);
 }
 
+void WebLayerTreeRenderer::setContentsSize(const WebCore::FloatSize& contentsSize)
+{
+    m_contentsSize = contentsSize;
+}
+
 void WebLayerTreeRenderer::setVisibleContentsRect(const IntRect& rect, float scale)
 {
     m_visibleContentsRect = rect;
@@ -155,6 +172,23 @@ void WebLayerTreeRenderer::updateViewport()
         m_layerTreeHostProxy->updateViewport();
 }
 
+void WebLayerTreeRenderer::adjustPositionForFixedLayers()
+{
+    if (m_fixedLayers.isEmpty())
+        return;
+
+    IntPoint scrollPosition = boundedScrollPosition(m_visibleContentsRect.location(), m_visibleContentsRect, m_contentsSize);
+
+    LayerMap::iterator end = m_fixedLayers.end();
+    for (LayerMap::iterator it = m_fixedLayers.begin(); it != end; ++it)
+        toTextureMapperLayer(it->second)->setScrollPositionDelta(IntPoint(scrollPosition.x() - m_renderedContentsScrollPosition.x(), scrollPosition.y() - m_renderedContentsScrollPosition.y()));
+}
+
+void WebLayerTreeRenderer::didChangeScrollPosition(const IntPoint& position)
+{
+    m_pendingRenderedContentsScrollPosition = boundedScrollPosition(position, m_visibleContentsRect, m_contentsSize);
+}
+
 void WebLayerTreeRenderer::setLayerChildren(WebLayerID id, const Vector<WebLayerID>& childIDs)
 {
     ensureLayer(id);
@@ -195,6 +229,11 @@ void WebLayerTreeRenderer::setLayerState(WebLayerID id, const WebLayerInfo& laye
     layer->setContentsRect(layerInfo.contentsRect);
     layer->setDrawsContent(layerInfo.drawsContent);
 
+    if (layerInfo.fixedToViewport)
+        m_fixedLayers.add(id, layer);
+    else
+        m_fixedLayers.remove(id);
+
     assignImageToLayer(layer, layerInfo.imageBackingStoreID);
 
     // Never make the root layer clip.
@@ -213,6 +252,7 @@ void WebLayerTreeRenderer::deleteLayer(WebLayerID layerID)
 
     layer->removeFromParent();
     m_layers.remove(layerID);
+    m_fixedLayers.remove(layerID);
     delete layer;
 }
 
@@ -310,6 +350,8 @@ void WebLayerTreeRenderer::commitTileOperations()
 
 void WebLayerTreeRenderer::flushLayerChanges()
 {
+    m_renderedContentsScrollPosition = m_pendingRenderedContentsScrollPosition;
+
     m_rootLayer->syncCompositingState(FloatRect());
     commitTileOperations();
 
index 357b087..4d5c7f1 100644 (file)
@@ -64,7 +64,9 @@ public:
     void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&);
     void paintToGraphicsContext(BackingStore::PlatformGraphicsContext);
     void syncRemoteContent();
+    void setContentsSize(const WebCore::FloatSize&);
     void setVisibleContentsRect(const WebCore::IntRect&, float scale);
+    void didChangeScrollPosition(const WebCore::IntPoint& position);
 
     void detach();
     void appendUpdate(const Function<void()>&);
@@ -94,8 +96,10 @@ private:
     virtual bool showRepaintCounter(const WebCore::GraphicsLayer*) const { return false; }
     void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect&) { }
     void callOnMainTread(const Function<void()>&);
+    void adjustPositionForFixedLayers();
 
     typedef HashMap<WebLayerID, WebCore::GraphicsLayer*> LayerMap;
+    WebCore::FloatSize m_contentsSize;
     WebCore::IntRect m_visibleContentsRect;
     float m_contentsScale;
 
@@ -124,7 +128,10 @@ private:
     Vector<WebLayerID> m_layersToDelete;
 
     LayerMap m_layers;
+    LayerMap m_fixedLayers;
     WebLayerID m_rootLayerID;
+    WebCore::IntPoint m_renderedContentsScrollPosition;
+    WebCore::IntPoint m_pendingRenderedContentsScrollPosition;
 };
 
 };
index bae9a0f..d80f2a6 100644 (file)
@@ -96,6 +96,7 @@ WebGraphicsLayer::WebGraphicsLayer(GraphicsLayerClient* client)
     : GraphicsLayer(client)
     , m_maskTarget(0)
     , m_inUpdateMode(false)
+    , m_fixedToViewport(false)
     , m_shouldUpdateVisibleRect(true)
     , m_shouldSyncLayerState(true)
     , m_shouldSyncChildren(true)
@@ -387,6 +388,8 @@ void WebGraphicsLayer::syncCompositingState(const FloatRect& rect)
     if (WebGraphicsLayer* replica = toWebGraphicsLayer(replicaLayer()))
         replica->syncCompositingStateForThisLayerOnly();
 
+    m_webGraphicsLayerClient->syncFixedLayers();
+
     syncCompositingStateForThisLayerOnly();
 
     for (size_t i = 0; i < children().size(); ++i)
@@ -415,6 +418,7 @@ void WebGraphicsLayer::syncLayerState()
     if (!m_shouldSyncLayerState)
         return;
     m_shouldSyncLayerState = false;
+    m_layerInfo.fixedToViewport = fixedToViewport();
 
     m_layerInfo.anchorPoint = anchorPoint();
     m_layerInfo.backfaceVisible = backfaceVisibility();
index 5329cdc..0ebbb51 100644 (file)
@@ -59,6 +59,7 @@ public:
     virtual void syncLayerChildren(WebLayerID, const Vector<WebLayerID>&) = 0;
     virtual void attachLayer(WebCore::WebGraphicsLayer*) = 0;
     virtual void detachLayer(WebCore::WebGraphicsLayer*) = 0;
+    virtual void syncFixedLayers() = 0;
     virtual PassOwnPtr<WebCore::GraphicsContext> beginContentUpdate(const WebCore::IntSize&, ShareableBitmap::Flags, ShareableSurface::Handle&, WebCore::IntPoint&) = 0;
 };
 }
@@ -111,6 +112,9 @@ public:
     void didSynchronize();
     Image* image() { return m_image.get(); }
 
+    bool fixedToViewport() const { return m_fixedToViewport; }
+    void setFixedToViewport(bool isFixed) { m_fixedToViewport = isFixed; }
+
     GraphicsLayer* maskTarget() const { return m_maskTarget; }
     void setMaskTarget(GraphicsLayer* layer) { m_maskTarget = layer; }
 
@@ -153,6 +157,7 @@ private:
     bool m_shouldUpdateVisibleRect: 1;
     bool m_shouldSyncLayerState: 1;
     bool m_shouldSyncChildren: 1;
+    bool m_fixedToViewport : 1;
 
     void notifyChange();
     void didChangeGeometry();
index 74856ba..84f467e 100644 (file)
@@ -835,6 +835,8 @@ void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSiz
     // Always reset even when empty.
     view->setFixedLayoutSize(targetLayoutSize);
 
+    m_page->settings()->setAcceleratedCompositingForFixedPositionEnabled(true);
+
     // Schedule a layout to use the new target size.
     if (!view->layoutPending()) {
         view->setNeedsLayout();
index 14e7c86..9bc0256 100644 (file)
 #include <WebCore/Frame.h>
 #include <WebCore/FrameView.h>
 #include <WebCore/Page.h>
+#include <WebCore/RenderLayer.h>
+#include <WebCore/RenderLayerBacking.h>
+#include <WebCore/RenderLayerCompositor.h>
+#include <WebCore/RenderView.h>
 #include <WebCore/Settings.h>
 
 using namespace WebCore;
@@ -68,6 +72,7 @@ LayerTreeHostQt::LayerTreeHostQt(WebPage* webPage)
     , m_waitingForUIProcess(false)
     , m_isSuspended(false)
     , m_contentsScale(1)
+    , m_shouldSendScrollPositionUpdate(true)
     , m_shouldSyncFrame(false)
     , m_shouldSyncRootLayer(true)
     , m_layerFlushTimer(this, &LayerTreeHostQt::layerFlushTimerFired)
@@ -230,6 +235,10 @@ bool LayerTreeHostQt::flushPendingLayerChanges()
 
 void LayerTreeHostQt::syncLayerState(WebLayerID id, const WebLayerInfo& info)
 {
+    if (m_shouldSendScrollPositionUpdate) {
+        m_webPage->send(Messages::LayerTreeHostProxy::DidChangeScrollPosition(m_visibleContentsRect.location()));
+        m_shouldSendScrollPositionUpdate = false;
+    }
     m_shouldSyncFrame = true;
     m_webPage->send(Messages::LayerTreeHostProxy::SetCompositingLayerState(id, info));
 }
@@ -256,6 +265,54 @@ void LayerTreeHostQt::detachLayer(WebGraphicsLayer* layer)
     m_webPage->send(Messages::LayerTreeHostProxy::DeleteCompositingLayer(layer->id()));
 }
 
+static void updateOffsetFromViewportForSelf(RenderLayer* renderLayer)
+{
+    // These conditions must match the conditions in RenderLayerCompositor::requiresCompositingForPosition.
+    RenderLayerBacking* backing = renderLayer->backing();
+    if (!backing)
+        return;
+
+    RenderStyle* style = renderLayer->renderer()->style();
+    if (!style)
+        return;
+
+    if (!renderLayer->renderer()->isPositioned() || renderLayer->renderer()->style()->position() != FixedPosition)
+        return;
+
+    if (!renderLayer->renderer()->container()->isRenderView())
+        return;
+
+    if (!renderLayer->isStackingContext())
+        return;
+
+    WebGraphicsLayer* graphicsLayer = toWebGraphicsLayer(backing->graphicsLayer());
+    graphicsLayer->setFixedToViewport(true);
+}
+
+static void updateOffsetFromViewportForLayer(RenderLayer* renderLayer)
+{
+    updateOffsetFromViewportForSelf(renderLayer);
+
+    if (renderLayer->firstChild())
+        updateOffsetFromViewportForLayer(renderLayer->firstChild());
+    if (renderLayer->nextSibling())
+        updateOffsetFromViewportForLayer(renderLayer->nextSibling());
+}
+
+void LayerTreeHostQt::syncFixedLayers()
+{
+    if (!m_webPage->corePage()->settings() || !m_webPage->corePage()->settings()->acceleratedCompositingForFixedPositionEnabled())
+        return;
+
+    if (!m_webPage->mainFrame()->view()->hasFixedObjects())
+        return;
+
+    RenderLayer* rootRenderLayer = m_webPage->mainFrame()->contentRenderer()->compositor()->rootRenderLayer();
+    ASSERT(rootRenderLayer);
+    if (rootRenderLayer->firstChild())
+        updateOffsetFromViewportForLayer(rootRenderLayer->firstChild());
+}
+
 void LayerTreeHostQt::performScheduledLayerFlush()
 {
     if (m_isSuspended || m_waitingForUIProcess)
@@ -447,6 +504,8 @@ void LayerTreeHostQt::setVisibleContentsRect(const IntRect& rect, float scale, c
     scheduleLayerFlush();
     if (m_webPage->useFixedLayout())
         m_webPage->setFixedVisibleContentRect(rect);
+    if (contentsRectDidChange)
+        m_shouldSendScrollPositionUpdate = true;
 }
 
 void LayerTreeHostQt::renderNextFrame()
index c293b18..b9f74ee 100644 (file)
@@ -76,6 +76,7 @@ public:
     virtual void syncLayerChildren(WebLayerID, const Vector<WebLayerID>&);
     virtual void attachLayer(WebCore::WebGraphicsLayer*);
     virtual void detachLayer(WebCore::WebGraphicsLayer*);
+    virtual void syncFixedLayers();
 
     virtual PassOwnPtr<WebCore::GraphicsContext> beginContentUpdate(const WebCore::IntSize&, ShareableBitmap::Flags, ShareableSurface::Handle&, WebCore::IntPoint&);
 
@@ -119,6 +120,7 @@ private:
     bool m_isSuspended;
     WebCore::IntRect m_visibleContentsRect;
     float m_contentsScale;
+    bool m_shouldSendScrollPositionUpdate;
 
     LayerTreeContext m_layerTreeContext;
     bool m_shouldSyncFrame;