summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Scott <phanna@android.com>2010-08-13 16:17:40 -0400
committerPatrick Scott <phanna@android.com>2010-08-16 12:39:44 -0400
commit726264480d16a18c02f405aff63a32ba06fb0476 (patch)
tree97f7b473af2ce50a7165849008c1a4f385da3c5f
parenta01792f8060881461b672472ba3dfdd77044e0a5 (diff)
downloadexternal_webkit-726264480d16a18c02f405aff63a32ba06fb0476.zip
external_webkit-726264480d16a18c02f405aff63a32ba06fb0476.tar.gz
external_webkit-726264480d16a18c02f405aff63a32ba06fb0476.tar.bz2
Update navigation in scrollable layers.
Set the foreground clip after drawing. Use the absolute bounds to compute the local foreground clip in order to compensate for any outline. Consolidate the check for overflow scrolling into RenderLayer. Request a compositing update after computing the scroll dimensions. Only change the foregroundRect of the layer during paint so that the outline rect (and background/layerBounds) are correct. Draw the outline as part of the background phase. During painting of a layer, scroll to (0,0), paint, then scroll back. When clicking on an element in a layer, scroll to the position of the element but do not scroll back. This makes text input fields visible to the tree and will properly update when typing. Record the original scroll position of layers in order to offset the bounds of nodes when checking the nav cache. Make sure to reset all cached layers during setRootLayer. Otherwise we were reaching into layers from the wrong thread. Change-Id: Id9827ec461989b0869a8252d4d2563ecd12c5fac
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp38
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.h2
-rw-r--r--WebCore/rendering/RenderLayer.cpp35
-rw-r--r--WebCore/rendering/RenderLayer.h3
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp51
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp7
-rw-r--r--WebKit/android/jni/WebViewCore.cpp37
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp23
-rw-r--r--WebKit/android/nav/CacheBuilder.h1
-rw-r--r--WebKit/android/nav/CachedLayer.cpp25
-rw-r--r--WebKit/android/nav/CachedLayer.h6
-rw-r--r--WebKit/android/nav/CachedRoot.h5
12 files changed, 155 insertions, 78 deletions
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index a5ca972..adbd18b 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -106,6 +106,12 @@ SkLength convertLength(Length l) {
return length;
}
+static RenderLayer* renderLayerFromClient(GraphicsLayerClient* client) {
+ if (client)
+ return static_cast<RenderLayerBacking*>(client)->owningLayer();
+ return 0;
+}
+
GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
GraphicsLayer(client),
m_needsSyncChildren(false),
@@ -122,9 +128,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_currentPosition(0, 0)
{
m_contentLayer = new LayerAndroid(true);
- if (m_client) {
- RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
- RenderLayer* renderLayer = backing->owningLayer();
+ RenderLayer* renderLayer = renderLayerFromClient(m_client);
+ if (renderLayer) {
m_contentLayer->setIsRootLayer(renderLayer->isRootLayer() &&
!(renderLayer->renderer()->frame()->ownerElement()));
}
@@ -224,8 +229,7 @@ void GraphicsLayerAndroid::updateFixedPosition()
if (!m_client)
return;
- RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_client);
- RenderLayer* renderLayer = backing->owningLayer();
+ RenderLayer* renderLayer = renderLayerFromClient(m_client);
RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
// If we are a fixed position layer, just set it
@@ -293,9 +297,6 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
GraphicsLayer::setSize(size);
m_contentLayer->setSize(size.width(), size.height());
- m_contentLayer->setForegroundClip(
- SkRect::MakeWH(SkFloatToScalar(size.width()),
- SkFloatToScalar(size.height())));
updateFixedPosition();
askForSync();
}
@@ -473,6 +474,22 @@ bool GraphicsLayerAndroid::repaint()
m_needsRepaint = false;
m_invalidatedRects.clear();
+ RenderLayer* layer = renderLayerFromClient(m_client);
+ // Use the absolute bounds of the renderer instead of the layer's
+ // bounds because the layer will add in the outline. What we want
+ // is the content bounds inside the outline.
+ FloatRect clip = layer->renderer()->absoluteBoundingBoxRect();
+ // Move the clip local to the layer position.
+ clip.move(-m_position.x(), -m_position.y());
+ if (layer->hasOverflowScroll()) {
+ // If this is a scrollable layer, inset the clip by the border.
+ RenderBox* box = layer->renderBox();
+ clip.move(box->borderLeft(), box->borderTop());
+ clip.setWidth(clip.width() - box->borderLeft() - box->borderRight());
+ clip.setHeight(clip.height() - box->borderTop() - box->borderBottom());
+ }
+ m_contentLayer->setForegroundClip(clip);
+
return true;
}
return false;
@@ -927,11 +944,6 @@ void GraphicsLayerAndroid::notifyClientAnimationStarted()
}
}
-void GraphicsLayerAndroid::setContentsClip(const IntRect& clip)
-{
- m_contentLayer->setForegroundClip(clip);
-}
-
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 7482969..80c92f3 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -115,8 +115,6 @@ public:
static int instancesCount();
- void setContentsClip(const IntRect& clip);
-
private:
void askForSync();
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index cc7eed0..ee1f1d4 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -1881,6 +1881,22 @@ bool RenderLayer::hasOverflowControls() const
{
return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
}
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+bool RenderLayer::hasOverflowScroll() const
+{
+ if (!enclosingElement()->hasTagName(HTMLNames::divTag))
+ return false;
+ if (m_scrollDimensionsDirty)
+ return false;
+ EOverflow x = renderer()->style()->overflowX();
+ if ((x == OSCROLL || x == OAUTO) && m_scrollWidth > renderBox()->clientWidth())
+ return true;
+ EOverflow y = renderer()->style()->overflowY();
+ if ((y == OSCROLL || y == OAUTO) && m_scrollHeight > renderBox()->clientHeight())
+ return true;
+ return false;
+}
+#endif
void RenderLayer::positionOverflowControls(int tx, int ty)
{
@@ -1954,6 +1970,13 @@ void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
*needHBar = rightPos > clientWidth;
if (needVBar)
*needVBar = bottomPos > clientHeight;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (hasOverflowScroll()) {
+ compositor()->setCompositingLayersNeedRebuild(true);
+ compositor()->enableCompositingMode(true);
+ compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange, this);
+ }
+#endif
}
void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
@@ -3219,13 +3242,11 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
// This layer establishes a clip of some kind.
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (renderer()->hasOverflowClip() &&
- !m_scrollDimensionsDirty &&
- (m_scrollWidth > renderBox()->clientWidth() ||
- m_scrollHeight > renderBox()->clientHeight())) {
+ if (hasOverflowScroll()) {
RenderBox* box = toRenderBox(renderer());
- layerBounds = backgroundRect = foregroundRect = outlineRect =
- IntRect(x, y, box->borderLeft() + box->borderRight() + m_scrollWidth,
+ foregroundRect =
+ IntRect(x, y,
+ box->borderLeft() + box->borderRight() + m_scrollWidth,
box->borderTop() + box->borderBottom() + m_scrollHeight);
} else
#endif
@@ -3743,7 +3764,7 @@ bool RenderLayer::shouldBeNormalFlowOnly() const
bool RenderLayer::isSelfPaintingLayer() const
{
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (renderer()->hasOverflowClip())
+ if (hasOverflowScroll())
return true;
#endif
return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow() || renderer()->isVideo() || renderer()->isEmbeddedObject() || renderer()->isRenderIFrame();
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index e8c290b..ba79292 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -265,6 +265,9 @@ public:
int horizontalScrollbarHeight() const;
bool hasOverflowControls() const;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ bool hasOverflowScroll() const;
+#endif
void positionOverflowControls(int tx, int ty);
bool isPointInResizeControl(const IntPoint& absolutePoint) const;
bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint);
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index 421196b..0db94dc 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -441,18 +441,6 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
m_graphicsLayer->setContentsRect(contentsBox());
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (m_owningLayer->hasOverflowControls()) {
- RenderBoxModelObject* box = renderer();
- IntRect clip = compositedBounds();
- IntPoint location = clip.location();
- location.move(box->borderLeft(), box->borderTop());
- clip.setLocation(location);
- clip.setWidth(clip.width() - box->borderLeft() - box->borderRight());
- clip.setHeight(clip.height() - box->borderTop() - box->borderBottom());
- static_cast<GraphicsLayerAndroid*>(m_graphicsLayer.get())->setContentsClip(clip);
- }
-#endif
updateDrawsContent();
updateAfterWidgetResize();
}
@@ -882,21 +870,17 @@ IntRect RenderLayerBacking::contentsBox() const
#endif
contentsRect = toRenderBox(renderer())->contentBoxRect();
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (m_owningLayer->hasOverflowControls()) {
+ if (m_owningLayer->hasOverflowScroll()) {
// Update the contents rect to have the width and height of the entire
// contents. This rect is only used by the platform GraphicsLayer and
// the position of the rectangle is ignored. Use the layer's scroll
// width/height (which contain the padding).
RenderBox* box = toRenderBox(renderer());
+ int outline = box->view()->maximalOutlineSize() << 1;
contentsRect.setWidth(box->borderLeft() + box->borderRight() +
- m_owningLayer->scrollWidth());
+ m_owningLayer->scrollWidth() + outline);
contentsRect.setHeight(box->borderTop() + box->borderBottom() +
- m_owningLayer->scrollHeight());
- // Move the contents rect by the padding since
- // RenderBox::contentBoxRect includes the padding. The end result is
- // to have a box representing the entires contents plus border and
- // padding. This will be the size of the underlying picture.
- contentsRect.setLocation(IntPoint(0, 0));
+ m_owningLayer->scrollHeight() + outline);
}
#endif
@@ -1021,6 +1005,17 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Restore the clip.
restoreClip(context, paintDirtyRect, damageRect);
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // Paint the outline as part of the background phase in order for the
+ // outline to not be a part of the scrollable content.
+ if (!outlineRect.isEmpty()) {
+ // Paint our own outline
+ PaintInfo paintInfo(context, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
+ setClip(context, paintDirtyRect, outlineRect);
+ renderer()->paint(paintInfo, tx, ty);
+ restoreClip(context, paintDirtyRect, outlineRect);
+ }
+#endif
// Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint.
m_owningLayer->paintList(m_owningLayer->negZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0);
@@ -1030,6 +1025,13 @@ 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();
+ 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,
@@ -1051,6 +1053,9 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
// Now restore our clip.
restoreClip(context, paintDirtyRect, clipRectToApply);
+#if !ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // Do not paint the outline as part of the foreground since it will
+ // appear inside the scrollable content.
if (!outlineRect.isEmpty()) {
// Paint our own outline
PaintInfo paintInfo(context, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
@@ -1058,12 +1063,16 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
renderer()->paint(paintInfo, tx, ty);
restoreClip(context, paintDirtyRect, outlineRect);
}
+#endif
// Paint any child layers that have overflow.
m_owningLayer->paintList(m_owningLayer->normalFlowList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, 0);
// 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)
+ m_owningLayer->scrollToOffset(x, y, false, false);
+#endif
}
if (shouldPaint && (paintingPhase & GraphicsLayerPaintMask)) {
@@ -1107,7 +1116,7 @@ void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& co
// can compute and cache clipRects.
IntRect enclosingBBox = compositedBounds();
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- if (m_owningLayer->hasOverflowControls()) {
+ if (m_owningLayer->hasOverflowScroll()) {
enclosingBBox.setSize(contentsBox().size());
enclosingBBox.setLocation(m_compositedBounds.location());
}
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 12c8a56..72a2d32 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1135,6 +1135,10 @@ bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
#if PLATFORM(ANDROID)
bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* layer) const
{
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (layer->hasOverflowScroll())
+ return true;
+#endif
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
// First, check if we are in an iframe, and if so bail out
if (m_renderView->document()->frame()->tree()->parent())
@@ -1174,9 +1178,6 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c
return requiresCompositingForTransform(renderer)
#if PLATFORM(ANDROID)
|| requiresCompositingForMobileSites(layer)
-#if ENABLE(ANDROID_OVERFLOW_SCROLL)
- || renderer->hasOverflowClip()
-#endif
#endif
|| requiresCompositingForVideo(renderer)
|| requiresCompositingForCanvas(renderer)
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 1ed885a..31c6120 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2360,7 +2360,8 @@ void WebViewCore::touchUp(int touchGeneration,
// Return the RenderLayer for the given RenderObject only if the layer is
// composited and it contains a scrollable content layer.
-static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* renderer)
+static WebCore::RenderLayer* getLayerFromRenderer(
+ WebCore::RenderObject* renderer, LayerAndroid** aLayer)
{
if (!renderer)
return 0;
@@ -2371,9 +2372,10 @@ static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* rendere
static_cast<GraphicsLayerAndroid*>(layer->backing()->graphicsLayer());
if (!graphicsLayer)
return 0;
- LayerAndroid* aLayer = graphicsLayer->contentLayer();
- if (!aLayer || !aLayer->contentIsScrollable())
+ LayerAndroid* layerAndroid = graphicsLayer->contentLayer();
+ if (!layerAndroid || !layerAndroid->contentIsScrollable())
return 0;
+ *aLayer = layerAndroid;
return layer;
}
@@ -2381,34 +2383,27 @@ static WebCore::RenderLayer* getLayerFromRenderer(WebCore::RenderObject* rendere
// done so that the node is visible when it is clicked.
static void scrollLayer(WebCore::RenderObject* renderer, WebCore::IntPoint* pos)
{
- WebCore::RenderLayer* layer = getLayerFromRenderer(renderer);
+ LayerAndroid* aLayer;
+ WebCore::RenderLayer* layer = getLayerFromRenderer(renderer, &aLayer);
if (!layer)
return;
WebCore::IntRect absBounds = renderer->absoluteBoundingBoxRect();
- WebCore::IntRect layerBounds = layer->absoluteBoundingBox();
+ // Do not include the outline when moving the node's bounds.
+ WebCore::IntRect layerBounds = layer->renderer()->absoluteBoundingBoxRect();
// Move the node's bounds into the layer's coordinates.
absBounds.move(-layerBounds.x(), -layerBounds.y());
+ int diffX = layer->scrollXOffset();
+ int diffY = layer->scrollYOffset();
// Scroll the layer to the node's position. The false parameters tell the
// layer not to invalidate.
- layer->scrollToOffset(absBounds.x(), absBounds.y(), false, false);
+ layer->scrollToOffset(absBounds.x(), absBounds.y(), false, true);
+ diffX = layer->scrollXOffset() - diffX;
+ diffY = layer->scrollYOffset() - diffY;
// Update the mouse position to the layer offset.
- pos->move(-layer->scrollXOffset(), -layer->scrollYOffset());
-}
-
-static void restoreScrolledLayer(WebCore::RenderObject* renderer,
- WebCore::IntPoint* pos)
-{
- WebCore::RenderLayer* layer = getLayerFromRenderer(renderer);
- if (!layer)
- return;
- // Move the mouse position back to it's original position.
- pos->move(layer->scrollXOffset(), layer->scrollYOffset());
-
- // Scroll the layer back to 0,0.
- layer->scrollToOffset(0, 0, false, false);
+ pos->move(-diffX, -diffY);
}
// Common code for both clicking with the trackball and touchUp
@@ -2508,8 +2503,6 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
requestKeyboard(true);
}
}
- if (nodePtr && valid)
- restoreScrolledLayer(nodePtr->renderer(), &m_mousePos);
return handled;
}
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index e76c729..c05395c 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -915,7 +915,7 @@ static bool checkForPluginViewThatWantsFocus(RenderObject* renderer) {
#if USE(ACCELERATED_COMPOSITING)
static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
- int id)
+ const IntPoint& scroll, int id)
{
DBG_NAV_LOGD("frame=%p index=%d loc=(%d,%d) id=%d", frame, index,
location.x(), location.y(), id);
@@ -923,6 +923,7 @@ static void AddLayer(CachedFrame* frame, size_t index, const IntPoint& location,
cachedLayer.reset();
cachedLayer.setCachedNodeIndex(index);
cachedLayer.setOffset(location);
+ cachedLayer.setScrollOffset(scroll);
cachedLayer.setUniqueId(id);
frame->add(cachedLayer);
}
@@ -1063,12 +1064,16 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
TrackLayer(layerTracker, nodeRenderer, lastChild,
globalOffsetX, globalOffsetY);
size_t size = tracker.size();
- const LayerAndroid* layer = layerTracker.last().mLayer;
+ LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
int id = layer->uniqueId();
- IntPoint loc = nodeRenderer->
- absoluteBoundingBoxRect().location();
+ const RenderLayer* renderLayer =
+ layerTracker.last().mRenderLayer;
+ IntPoint loc(SkScalarRound(layer->getPosition().fX),
+ SkScalarRound(layer->getPosition().fY));
loc.move(globalOffsetX, globalOffsetY);
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
// if this is a child of a CachedNode, add a layer
size_t limit = cachedFrame->layerCount() == 0 ? 0 :
cachedFrame->lastLayer()->cachedNodeIndex();
@@ -1084,7 +1089,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
CachedNode* trackedNode = cachedFrame->getIndex(index);
trackedNode->setIsInLayer(true);
trackedNode->setIsUnclipped(true);
- AddLayer(cachedFrame, index, loc, id);
+ AddLayer(cachedFrame, index, loc, scroll, id);
}
}
}
@@ -1327,6 +1332,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
LayerAndroid* layer = layerTracker.last().mLayer;
if (layer) {
const IntRect& layerClip = layerTracker.last().mBounds;
+ const RenderLayer* renderLayer = layerTracker.last().mRenderLayer;
if (!layer->contentIsScrollable() && !layerClip.isEmpty() &&
!cachedNode.clip(layerClip)) {
DBG_NAV_LOGD("skipped on layer clip %d", cacheIndex);
@@ -1334,8 +1340,10 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
}
isInLayer = true;
isUnclipped = true; // assume that layers do not have occluded nodes
+ IntPoint scroll(renderLayer->scrollXOffset(),
+ renderLayer->scrollYOffset());
AddLayer(cachedFrame, cachedFrame->size(), layerClip.location(),
- layer->uniqueId());
+ scroll, layer->uniqueId());
}
#endif
cachedNode.setNavableRects();
@@ -2838,7 +2846,8 @@ void CacheBuilder::TrackLayer(WTF::Vector<LayerTracker>& layerTracker,
layerTracker.grow(layerTracker.size() + 1);
LayerTracker& indexTracker = layerTracker.last();
indexTracker.mLayer = aLayer;
- indexTracker.mBounds = nodeRenderer->absoluteBoundingBoxRect();
+ indexTracker.mRenderLayer = layer;
+ indexTracker.mBounds = IntRect(FloatRect(aLayer->bounds()));
indexTracker.mBounds.move(offsetX, offsetY);
indexTracker.mLastChild = lastChild ? OneAfter(lastChild) : 0;
DBG_NAV_LOGD("layer=%p [%d] bounds=(%d,%d,w=%d,h=%d)", aLayer,
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 5324187..d19e0c9 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -198,6 +198,7 @@ private:
};
struct LayerTracker : Tracker {
LayerAndroid* mLayer;
+ RenderLayer* mRenderLayer;
IntRect mBounds;
};
struct TabIndexTracker : Tracker {
diff --git a/WebKit/android/nav/CachedLayer.cpp b/WebKit/android/nav/CachedLayer.cpp
index 9c7d59b..c4293a5 100644
--- a/WebKit/android/nav/CachedLayer.cpp
+++ b/WebKit/android/nav/CachedLayer.cpp
@@ -49,6 +49,10 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
// First, remove the original offset from the bounds.
temp.move(-mOffset.x(), -mOffset.y());
+ // Now, add in the original scroll position. This moves the node to the
+ // original location within the layer.
+ temp.move(mScrollOffset.x(), mScrollOffset.y());
+
// Next, add in the new position of the layer (could be different due to a
// fixed position layer).
const FloatPoint& position = aLayer->getPosition();
@@ -72,12 +76,17 @@ IntRect CachedLayer::adjustBounds(const LayerAndroid* root,
DBG_NAV_LOGD("root=%p aLayer=%p [%d]"
" bounds=(%d,%d,w=%d,h=%d) trans=(%g,%g)"
+ " pos=(%f,%f)"
" offset=(%d,%d) clip=(%d,%d,w=%d,h=%d)"
+ " scroll=(%d,%d) origScroll=(%d,%d)"
" result=(%d,%d,w=%d,h=%d)",
root, aLayer, aLayer->uniqueId(),
bounds.x(), bounds.y(), bounds.width(), bounds.height(),
- translation.x(), translation.y(), mOffset.x(), mOffset.y(),
+ translation.x(), translation.y(), position.x(), position.y(),
+ mOffset.x(), mOffset.y(),
clip.x(), clip.y(), clip.width(), clip.height(),
+ SkScalarRound(scroll.fX), SkScalarRound(scroll.fY),
+ mScrollOffset.x(), mScrollOffset.y(),
result.x(), result.y(), result.width(), result.height());
return result;
}
@@ -104,6 +113,9 @@ IntRect CachedLayer::unadjustBounds(const LayerAndroid* root,
// Move it back to the original offset.
temp.move(mOffset.x(), mOffset.y());
+
+ // Move the bounds by the original scroll.
+ temp.move(-mScrollOffset.x(), -mScrollOffset.y());
return temp;
}
@@ -122,6 +134,10 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
// Remove the original offset from the bounds.
temp.move(-mOffset.x(), -mOffset.y());
+ // We add in the original scroll position in order to position the node
+ // relative to the current internal scroll position.
+ temp.move(mScrollOffset.x(), mScrollOffset.y());
+
const LayerAndroid* aLayer = layer(root);
if (aLayer) {
// Move the bounds by the scroll position of the layer.
@@ -134,7 +150,12 @@ IntRect CachedLayer::localBounds(const LayerAndroid* root,
temp.intersect(IntRect(aLayer->foregroundClip()));
}
- return enclosingIntRect(temp);
+ DBG_NAV_LOGD("bounds=(%d,%d,w=%d,h=%d) offset=(%d,%d)"
+ " result=(%d,%d,w=%d,h=%d)", bounds.x(), bounds.y(),
+ bounds.width(), bounds.height(), mOffset.x(), mOffset.y(),
+ temp.x(), temp.y(), temp.width(), temp.height());
+
+ return temp;
}
SkPicture* CachedLayer::picture(const LayerAndroid* root) const
diff --git a/WebKit/android/nav/CachedLayer.h b/WebKit/android/nav/CachedLayer.h
index 8bfe922..0a56ea1 100644
--- a/WebKit/android/nav/CachedLayer.h
+++ b/WebKit/android/nav/CachedLayer.h
@@ -58,12 +58,18 @@ public:
void reset() { mLayer = 0; }
void setCachedNodeIndex(int index) { mCachedNodeIndex = index; }
void setOffset(const IntPoint& offset) { mOffset = offset; }
+ void setScrollOffset(const IntPoint& scrollOffset) {
+ mScrollOffset = scrollOffset;
+ }
void setUniqueId(int uniqueId) { mUniqueId = uniqueId; }
int uniqueId() const { return mUniqueId; }
private:
int mCachedNodeIndex;
mutable const LayerAndroid* mLayer;
+ // mOffset and mScrollOffset are the position and scroll offset of the
+ // layer when recorded by the nav cache.
IntPoint mOffset;
+ IntPoint mScrollOffset;
int mUniqueId;
#if DUMP_NAV_CACHE
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index 2853241..a6420f9 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -96,7 +96,10 @@ public:
void setTextGeneration(int textGeneration) { mTextGeneration = textGeneration; }
void setMaxScroll(int x, int y) { mMaxXScroll = x; mMaxYScroll = y; }
void setPicture(SkPicture* picture) { mPicture = picture; }
- void setRootLayer(WebCore::LayerAndroid* layer) { mRootLayer = layer; }
+ void setRootLayer(WebCore::LayerAndroid* layer) {
+ mRootLayer = layer;
+ resetLayers();
+ }
void setScrollOnly(bool state) { mScrollOnly = state; }
void setSelection(int start, int end) { mSelectionStart = start; mSelectionEnd = end; }
void setupScrolledBounds() const { mScrolledBounds = mViewBounds; }