summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp132
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.h1
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp12
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp4
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp2
5 files changed, 106 insertions, 45 deletions
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index e887964..49f20ab 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -271,7 +271,17 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
if (point == m_position)
return;
- GraphicsLayer::setPosition(point);
+ FloatPoint pos(point);
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // Add the scroll position back in. When scrolling a layer, all the children
+ // are positioned based on the content scroll. Adding the scroll position
+ // back in allows the children to draw based on 0,0.
+ RenderLayer* layer = renderLayerFromClient(m_client);
+ if (layer && layer->parent() && layer->parent()->hasOverflowScroll())
+ pos += layer->parent()->scrolledContentOffset();
+#endif
+
+ GraphicsLayer::setPosition(pos);
#ifdef LAYER_DEBUG_2
LOG("(%x) setPosition(%.2f,%.2f) pos(%.2f, %.2f) anchor(%.2f,%.2f) size(%.2f, %.2f)",
@@ -279,7 +289,7 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point)
m_anchorPoint.x(), m_anchorPoint.y(), m_size.width(), m_size.height());
#endif
updateFixedPosition();
- m_contentLayer->setPosition(point.x(), point.y());
+ m_contentLayer->setPosition(pos.x(), pos.y());
askForSync();
}
@@ -368,31 +378,6 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
if (m_contentLayer->isRootLayer())
return;
if (m_drawsContent) {
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- RenderLayer* layer = renderLayerFromClient(m_client);
- if (layer) {
- if (layer->hasOverflowScroll() && !m_foregroundLayer) {
- m_foregroundLayer = new ScrollableLayerAndroid();
- m_foregroundClipLayer = new LayerAndroid(false);
- m_foregroundClipLayer->setMasksToBounds(true);
-
- m_foregroundClipLayer->addChild(m_foregroundLayer);
- m_contentLayer->addChild(m_foregroundClipLayer);
- } else if (layer->isRootLayer()
- && layer->renderer()->frame()->ownerRenderer()) {
- // We have to do another check for scrollable content since an
- // iframe might be compositing for other reasons.
- FrameView* view = layer->renderer()->frame()->view();
- if (view->hasOverflowScroll()) {
- // Replace the content layer with a scrollable layer.
- LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer);
- m_contentLayer->unref();
- m_contentLayer = layer;
- }
- }
- }
-#endif
-
m_haveContents = true;
setNeedsDisplay();
}
@@ -478,6 +463,79 @@ private:
GraphicsLayerPaintingPhase m_originalPhase;
};
+void GraphicsLayerAndroid::updateScrollingLayers()
+{
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ RenderLayer* layer = renderLayerFromClient(m_client);
+ if (!layer)
+ return;
+ bool hasOverflowScroll = m_foregroundLayer || m_contentLayer->contentIsScrollable();
+ bool layerNeedsOverflow = layer->hasOverflowScroll();
+ bool iframeNeedsOverflow = layer->isRootLayer() &&
+ layer->renderer()->frame()->ownerRenderer() &&
+ layer->renderer()->frame()->view()->hasOverflowScroll();
+
+ if (hasOverflowScroll && (layerNeedsOverflow || iframeNeedsOverflow)) {
+ // Already has overflow layers.
+ return;
+ }
+ if (!hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow) {
+ // Does not need overflow layers.
+ return;
+ }
+ if (layerNeedsOverflow || iframeNeedsOverflow) {
+ ASSERT(!hasOverflowScroll);
+ if (layerNeedsOverflow) {
+ ASSERT(!m_foregroundLayer && !m_foregroundClipLayer);
+ m_foregroundLayer = new ScrollableLayerAndroid();
+ m_foregroundClipLayer = new LayerAndroid(false);
+ m_foregroundClipLayer->setMasksToBounds(true);
+ m_foregroundClipLayer->addChild(m_foregroundLayer);
+ m_contentLayer->addChild(m_foregroundClipLayer);
+ } else {
+ ASSERT(iframeNeedsOverflow && !m_contentLayer->contentIsScrollable());
+ // No need to copy the children as they will be removed and synced.
+ m_contentLayer->removeChildren();
+ // Replace the content layer with a scrollable layer.
+ LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer);
+ m_contentLayer->unref();
+ m_contentLayer = layer;
+ if (m_parent) {
+ // The content layer has changed so the parent needs to sync
+ // children.
+ static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
+ }
+ }
+ // Need to rebuild our children based on the new structure.
+ m_needsSyncChildren = true;
+ askForSync();
+ } else {
+ ASSERT(hasOverflowScroll && !layerNeedsOverflow && !iframeNeedsOverflow);
+ ASSERT(m_contentLayer);
+ // Remove the foreground layers.
+ if (m_foregroundLayer) {
+ m_foregroundLayer->unref();
+ m_foregroundLayer = 0;
+ m_foregroundClipLayer->unref();
+ m_foregroundClipLayer = 0;
+ }
+ // No need to copy over children.
+ m_contentLayer->removeChildren();
+ LayerAndroid* layer = new LayerAndroid(*m_contentLayer);
+ m_contentLayer->unref();
+ m_contentLayer = layer;
+ if (m_parent) {
+ // The content layer has changed so the parent needs to sync
+ // children.
+ static_cast<GraphicsLayerAndroid*>(m_parent)->m_needsSyncChildren = true;
+ }
+ // Children are all re-parented.
+ m_needsSyncChildren = true;
+ askForSync();
+ }
+#endif
+}
+
bool GraphicsLayerAndroid::repaint()
{
LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
@@ -506,8 +564,13 @@ bool GraphicsLayerAndroid::repaint()
m_foregroundLayer->setSize(contentsRect.width(), contentsRect.height());
// Paint everything else into the main recording canvas.
phase.clear(GraphicsLayerPaintBackground);
- if (!paintContext(m_foregroundLayer->recordContext(), contentsRect))
- return false;
+
+ // Paint at 0,0.
+ IntSize scroll = layer->scrolledContentOffset();
+ layer->scrollToOffset(0, 0, true, false);
+ // At this point, it doesn't matter if painting failed.
+ (void) paintContext(m_foregroundLayer->recordContext(), contentsRect);
+ layer->scrollToOffset(scroll.width(), scroll.height(), true, false);
// Construct the clip layer for masking the contents.
IntRect clip = layer->renderer()->absoluteBoundingBoxRect();
@@ -830,10 +893,16 @@ void GraphicsLayerAndroid::syncChildren()
{
if (m_needsSyncChildren) {
m_contentLayer->removeChildren();
- if (m_foregroundClipLayer)
+ LayerAndroid* layer = m_contentLayer;
+ if (m_foregroundClipLayer) {
m_contentLayer->addChild(m_foregroundClipLayer);
+ // Use the scrollable content layer as the parent of the children so
+ // that they move with the content.
+ layer = m_foregroundLayer;
+ layer->removeChildren();
+ }
for (unsigned int i = 0; i < m_children.size(); i++)
- m_contentLayer->addChild(m_children[i]->platformLayer());
+ layer->addChild(m_children[i]->platformLayer());
m_needsSyncChildren = false;
}
}
@@ -857,6 +926,7 @@ void GraphicsLayerAndroid::syncCompositingState()
for (unsigned int i = 0; i < m_children.size(); i++)
m_children[i]->syncCompositingState();
+ updateScrollingLayers();
syncChildren();
syncMask();
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index ce6bac1..da247ca 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -127,6 +127,7 @@ private:
void syncMask();
void updateFixedPosition();
+ void updateScrollingLayers();
// with SkPicture, we always repaint the entire layer's content.
bool repaint();
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 48aa3ec..0d39f7a 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -1021,14 +1021,6 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
bool selectionOnly = paintBehavior & PaintBehaviorSelectionOnly;
if (shouldPaint && (paintingPhase & GraphicsLayerPaintForeground)) {
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- // Scroll to 0,0 and paint the entire contents, then scroll back the
- // the original offset.
- int x = m_owningLayer->scrollXOffset();
- int y = m_owningLayer->scrollYOffset();
- if (m_owningLayer->hasOverflowScroll())
- m_owningLayer->scrollToOffset(0, 0, false, false);
-#endif
// Set up the clip used when painting our children.
setClip(context, paintDirtyRect, clipRectToApply);
PaintInfo paintInfo(context, clipRectToApply,
@@ -1067,10 +1059,6 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Now walk the sorted list of children with positive z-indices.
m_owningLayer->paintList(m_owningLayer->posZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0);
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (m_owningLayer->hasOverflowScroll())
- m_owningLayer->scrollToOffset(x, y, false, false);
-#endif
}
if (shouldPaint && (paintingPhase & GraphicsLayerPaintMask)) {
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index f31ab9d..9775134 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1288,6 +1288,10 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
// into the hierarchy between this layer and its children in the z-order hierarchy.
bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
{
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (layer->hasOverflowScroll())
+ return false;
+#endif
return layer->hasCompositingDescendant() &&
(layer->renderer()->hasOverflowClip() || layer->renderer()->hasClip());
}
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index fb5701a..980c03e 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -87,8 +87,6 @@ void ChromeClientAndroid::attachRootGraphicsLayer(WebCore::Frame*, WebCore::Grap
{
// frame is not used in Android as we should only get root graphics layer for the main frame
m_rootGraphicsLayer = layer;
- if (!layer)
- return;
scheduleCompositingLayerSync();
}