From fe812d40b53dc52d5c929e39b5e293af8b6cb4e4 Mon Sep 17 00:00:00 2001 From: Patrick Scott Date: Thu, 9 Dec 2010 18:12:20 -0500 Subject: [PATCH] Fix hit testing inside layers. * Prevent asking for a sync in GraphicsLayerAndroid if some property has not changed. * Remove scrolling logic from LayerAndroid and create a subclass for scrollable layers. * Report the scrolling limits to the layer in order to scroll iframes (not turned on) and to avoid computing them each time the layer is scrolled. * Change the foreground rect calculations to better match the non-overflow case. * During hit testing, intersect the hitTestClip with the foreground and background to prevent false positives in the layer. * Prepare for iframe scrolling by adding code to trigger compositing for iframes. This currently works great except for navigation so it disabled for now. Bug: 3258631 Change-Id: I0da2d8dbe25376c6aa4f485c9350048c82c6f563 --- WebCore/Android.mk | 1 + .../graphics/android/GraphicsLayerAndroid.cpp | 69 ++++++++++++++++------ .../graphics/android/GraphicsLayerAndroid.h | 4 +- WebCore/platform/graphics/android/LayerAndroid.cpp | 45 +------------- WebCore/platform/graphics/android/LayerAndroid.h | 18 +----- .../graphics/android/ScrollableLayerAndroid.cpp | 37 ++++++++++++ .../graphics/android/ScrollableLayerAndroid.h | 65 ++++++++++++++++++++ WebCore/rendering/RenderLayer.cpp | 19 ++++-- WebCore/rendering/RenderLayer.h | 16 +++++ WebCore/rendering/RenderLayerCompositor.cpp | 5 ++ WebKit/android/nav/WebView.cpp | 15 ++--- 11 files changed, 201 insertions(+), 93 deletions(-) create mode 100644 WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp create mode 100644 WebCore/platform/graphics/android/ScrollableLayerAndroid.h diff --git a/WebCore/Android.mk b/WebCore/Android.mk index fda531837..af6353e81 100644 --- a/WebCore/Android.mk +++ b/WebCore/Android.mk @@ -614,6 +614,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/PathAndroid.cpp \ platform/graphics/android/PatternAndroid.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ + platform/graphics/android/ScrollableLayerAndroid.cpp \ platform/graphics/android/SharedBufferStream.cpp \ platform/graphics/android/ShaderProgram.cpp \ platform/graphics/android/SharedTexture.cpp \ diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index fe7b13288..0fdbc217a 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -32,6 +32,7 @@ #include "RenderView.h" #include "RotateTransformOperation.h" #include "ScaleTransformOperation.h" +#include "ScrollableLayerAndroid.h" #include "SkCanvas.h" #include "TransformationMatrix.h" #include "TranslateTransformOperation.h" @@ -263,6 +264,8 @@ void GraphicsLayerAndroid::updateFixedPosition() void GraphicsLayerAndroid::setPosition(const FloatPoint& point) { + if (point == m_currentPosition) + return; m_currentPosition = point; m_needsDisplay = true; #ifdef LAYER_DEBUG_2 @@ -276,6 +279,8 @@ void GraphicsLayerAndroid::setPosition(const FloatPoint& point) void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point) { + if (point == m_anchorPoint) + return; GraphicsLayer::setAnchorPoint(point); m_contentLayer->setAnchorPoint(point.x(), point.y()); askForSync(); @@ -283,14 +288,13 @@ void GraphicsLayerAndroid::setAnchorPoint(const FloatPoint3D& point) void GraphicsLayerAndroid::setSize(const FloatSize& size) { - if ((size.width() != m_size.width()) - || (size.height() != m_size.height())) { - MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height()); - GraphicsLayer::setSize(size); - m_contentLayer->setSize(size.width(), size.height()); - updateFixedPosition(); - askForSync(); - } + if (size == m_size) + return; + MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height()); + GraphicsLayer::setSize(size); + m_contentLayer->setSize(size.width(), size.height()); + updateFixedPosition(); + askForSync(); } void GraphicsLayerAndroid::setTransform(const TransformationMatrix& t) @@ -329,7 +333,7 @@ void GraphicsLayerAndroid::setChildrenTransform(const TransformationMatrix& t) void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer) { if (layer == m_maskLayer) - return; + return; GraphicsLayer::setMaskLayer(layer); m_needsSyncMask = true; @@ -338,6 +342,8 @@ void GraphicsLayerAndroid::setMaskLayer(GraphicsLayer* layer) void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds) { + if (masksToBounds == m_masksToBounds) + return; GraphicsLayer::setMasksToBounds(masksToBounds); m_needsSyncMask = true; askForSync(); @@ -345,20 +351,30 @@ void GraphicsLayerAndroid::setMasksToBounds(bool masksToBounds) void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) { + if (drawsContent == m_drawsContent) + return; GraphicsLayer::setDrawsContent(drawsContent); if (m_contentLayer->isRootLayer()) return; if (m_drawsContent) { #if ENABLE(ANDROID_OVERFLOW_SCROLL) RenderLayer* layer = renderLayerFromClient(m_client); - if (layer && layer->hasOverflowScroll() && !m_foregroundLayer) { - m_foregroundLayer = new LayerAndroid(false); - m_foregroundLayer->setContentScrollable(true); - m_foregroundClipLayer = new LayerAndroid(false); - m_foregroundClipLayer->setMasksToBounds(true); - - m_foregroundClipLayer->addChild(m_foregroundLayer); - m_contentLayer->addChild(m_foregroundClipLayer); + 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 (false /* FIXME: disable until navigation is fixed */ && + layer->isRootLayer() && + layer->renderer()->frame()->ownerRenderer()) { + // Replace the content layer with a scrollable layer. + LayerAndroid* layer = new ScrollableLayerAndroid(*m_contentLayer); + m_contentLayer->unref(); + m_contentLayer = layer; + } } #endif @@ -370,6 +386,8 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent) void GraphicsLayerAndroid::setBackgroundColor(const Color& color) { + if (color == m_backgroundColor) + return; LOG("(%x) setBackgroundColor", this); GraphicsLayer::setBackgroundColor(color); SkColor c = SkColorSetARGB(color.alpha(), color.red(), color.green(), color.blue()); @@ -387,6 +405,8 @@ void GraphicsLayerAndroid::clearBackgroundColor() void GraphicsLayerAndroid::setContentsOpaque(bool opaque) { + if (opaque == m_contentsOpaque) + return; LOG("(%x) setContentsOpaque (%d)", this, opaque); GraphicsLayer::setContentsOpaque(opaque); m_haveContents = true; @@ -449,6 +469,7 @@ bool GraphicsLayerAndroid::repaint() // with SkPicture, we request the entire layer's content. IntRect layerBounds(0, 0, m_size.width(), m_size.height()); + RenderLayer* layer = renderLayerFromClient(m_client); if (m_foregroundLayer) { PaintingPhase phase(this); // Paint the background into a separate context. @@ -456,7 +477,6 @@ bool GraphicsLayerAndroid::repaint() if (!paintContext(m_contentLayer->recordContext(), layerBounds)) return false; - RenderLayer* layer = renderLayerFromClient(m_client); // Construct the foreground layer and draw. RenderBox* box = layer->renderBox(); int outline = box->view()->maximalOutlineSize(); @@ -485,11 +505,20 @@ bool GraphicsLayerAndroid::repaint() // Need to offset the foreground layer by the clip layer in order // for the contents to be in the correct position. m_foregroundLayer->setPosition(-x, -y); + // Set the scrollable bounds of the layer. + m_foregroundLayer->setScrollLimits(-x, -y, m_size.width(), m_size.height()); } else { // If there is no contents clip, we can draw everything into one // picture. if (!paintContext(m_contentLayer->recordContext(), layerBounds)) return false; + // Check for a scrollable iframe and report the scrolling + // limits based on the view size. + if (m_contentLayer->contentIsScrollable()) { + FrameView* view = layer->renderer()->frame()->view(); + static_cast(m_contentLayer)->setScrollLimits( + m_position.x(), m_position.y(), view->layoutWidth(), view->layoutHeight()); + } } TLOG("(%x) repaint() on (%.2f,%.2f) contentlayer(%.2f,%.2f,%.2f,%.2f)paintGraphicsLayer called!", @@ -579,7 +608,7 @@ bool GraphicsLayerAndroid::addAnimation(const KeyframeValueList& valueList, double beginTime) { if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() != 2) - return false; + return false; bool createdAnimations = false; if (valueList.property() == AnimatedPropertyWebkitTransform) { @@ -882,6 +911,8 @@ void GraphicsLayerAndroid::setDebugBorder(const Color& color, float borderWidth) void GraphicsLayerAndroid::setZPosition(float position) { + if (position == m_zPosition) + return; LOG("(%x) setZPosition: %.2f", this, position); GraphicsLayer::setZPosition(position); askForSync(); diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 098ad37b5..ea8c5c952 100644 --- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -32,6 +32,8 @@ class Image; namespace WebCore { +class ScrollableLayerAndroid; + class GraphicsLayerAndroid : public GraphicsLayer { public: @@ -149,7 +151,7 @@ private: Vector m_invalidatedRects; LayerAndroid* m_contentLayer; - LayerAndroid* m_foregroundLayer; + ScrollableLayerAndroid* m_foregroundLayer; LayerAndroid* m_foregroundClipLayer; }; diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index ca9a0e31b..f02136a12 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -51,7 +51,6 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), m_haveClip(false), m_doRotation(false), m_isFixed(false), - m_contentScrollable(false), m_recordingPicture(0), m_contentsImage(0), m_extra(0), @@ -68,7 +67,6 @@ LayerAndroid::LayerAndroid(bool isRootLayer) : SkLayer(), LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), m_isRootLayer(layer.m_isRootLayer), m_haveClip(layer.m_haveClip), - m_contentScrollable(layer.m_contentScrollable), m_extra(0), // deliberately not copied m_uniqueId(layer.m_uniqueId) { @@ -96,7 +94,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer), SkSafeRef(m_recordingPicture); for (int i = 0; i < layer.countChildren(); i++) - addChild(new LayerAndroid(*layer.getChild(i)))->unref(); + addChild(layer.getChild(i)->copy())->unref(); KeyframesMap::const_iterator end = layer.m_animations.end(); for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) @@ -110,7 +108,6 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(), m_haveClip(false), m_doRotation(false), m_isFixed(false), - m_contentScrollable(false), m_recordingPicture(picture), m_contentsImage(0), m_extra(0), @@ -476,46 +473,6 @@ SkPicture* LayerAndroid::recordContext() return 0; } -bool LayerAndroid::scrollTo(int x, int y) { - SkIRect scrollBounds; - getScrollRect(&scrollBounds); - if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0) - return false; - - SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight); - SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom); - // Check for no change. - if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop) - return false; - - SkScalar diffX = newX - scrollBounds.fLeft; - SkScalar diffY = newY - scrollBounds.fTop; - const SkPoint& pos = getPosition(); - setPosition(pos.fX - diffX, pos.fY - diffY); - return true; -} - -void LayerAndroid::getScrollRect(SkIRect* out) const { - if (!contentIsScrollable()) - return; - - // Scrollable layers have a mask layer and then the actual main layer. - if (getParent() == 0 || getParent()->getParent() == 0) - return; - LayerAndroid* realLayer = static_cast(getParent()->getParent()); - - SkRect scrollBounds; - realLayer->bounds(&scrollBounds); - - const SkPoint& maskLayerPosition = getParent()->getPosition(); - const SkPoint& pos = getPosition(); - // Our original position is the offset of the mask layer's position. - out->fLeft = maskLayerPosition.fX - pos.fX; - out->fTop = maskLayerPosition.fY - pos.fY; - out->fRight = getSize().width() - scrollBounds.width(); - out->fBottom = getSize().height() - scrollBounds.height(); -} - bool LayerAndroid::prepareContext(bool force) { if (masksToBounds()) diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 30f555598..510014b6f 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -131,15 +131,6 @@ public: SkPicture* recordContext(); - // Returns true if the content position has changed. - bool scrollTo(int dx, int dy); - // Fills the rect with the current scroll offset and the maximum scroll. - // fLeft = scrollX - // fTop = scrollY - // fRight = maxX - // fBottom = maxY - void getScrollRect(SkIRect* out) const; - void addAnimation(PassRefPtr anim); void removeAnimation(const String& name); bool evaluateAnimations() const; @@ -193,12 +184,8 @@ public: void bounds(SkRect* ) const; - bool contentIsScrollable() const { return m_contentScrollable; } - - // Set when building the layer hierarchy for scrollable elements. - void setContentScrollable(bool scrollable) { - m_contentScrollable = scrollable; - } + virtual bool contentIsScrollable() const { return false; } + virtual LayerAndroid* copy() const { return new LayerAndroid(*this); } protected: virtual void onDraw(SkCanvas*, SkScalar opacity); @@ -219,7 +206,6 @@ private: bool m_doRotation; bool m_isFixed; bool m_backgroundColorSet; - bool m_contentScrollable; SkLength m_fixedLeft; SkLength m_fixedTop; diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp new file mode 100644 index 000000000..7b40b8daa --- /dev/null +++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp @@ -0,0 +1,37 @@ +#include "config.h" +#include "ScrollableLayerAndroid.h" + +#if USE(ACCELERATED_COMPOSITING) + +namespace WebCore { + +bool ScrollableLayerAndroid::scrollTo(int x, int y) { + SkIRect scrollBounds; + getScrollRect(&scrollBounds); + if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0) + return false; + + SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight); + SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom); + // Check for no change. + if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop) + return false; + + SkScalar diffX = newX - scrollBounds.fLeft; + SkScalar diffY = newY - scrollBounds.fTop; + const SkPoint& pos = getPosition(); + setPosition(pos.fX - diffX, pos.fY - diffY); + return true; +} + +void ScrollableLayerAndroid::getScrollRect(SkIRect* out) const { + const SkPoint& pos = getPosition(); + out->fLeft = m_scrollLimits.fLeft - pos.fX; + out->fTop = m_scrollLimits.fTop - pos.fY; + out->fRight = getSize().width() - m_scrollLimits.width(); + out->fBottom = getSize().height() - m_scrollLimits.height(); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h new file mode 100644 index 000000000..d63625a94 --- /dev/null +++ b/WebCore/platform/graphics/android/ScrollableLayerAndroid.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ScrollableLayerAndroid_h +#define ScrollableLayerAndroid_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerAndroid.h" + +namespace WebCore { + +class ScrollableLayerAndroid : public LayerAndroid { + +public: + ScrollableLayerAndroid() + : LayerAndroid(false) {} + ScrollableLayerAndroid(const ScrollableLayerAndroid& layer) + : LayerAndroid(layer) + , m_scrollLimits(layer.m_scrollLimits) {} + ScrollableLayerAndroid(const LayerAndroid& layer) + : LayerAndroid(layer) { + m_scrollLimits.setEmpty(); + } + virtual ~ScrollableLayerAndroid() {}; + + virtual bool contentIsScrollable() const { return true; } + + virtual LayerAndroid* copy() const { return new ScrollableLayerAndroid(*this); } + + // Returns true if the content position has changed. + bool scrollTo(int dx, int dy); + // Fills the rect with the current scroll offset and the maximum scroll. + // fLeft = scrollX + // fTop = scrollY + // fRight = maxX + // fBottom = maxY + void getScrollRect(SkIRect* out) const; + + void setScrollLimits(float x, float y, float width, float height) { + m_scrollLimits.set(x, y, width, height); + } + +private: + SkRect m_scrollLimits; +}; + +} + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif // LayerAndroid_h diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index 42218162c..9d894af21 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -2945,6 +2945,14 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont candidateLayer = hitLayer; } +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + if (hasOverflowParent()) { + ClipRects clipRects; + calculateClipRects(rootLayer, clipRects, useTemporaryClipRects); + fgRect.intersect(clipRects.hitTestClip()); + bgRect.intersect(clipRects.hitTestClip()); + } +#endif // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. if (fgRect.intersects(hitTestArea) && isSelfPaintingLayer()) { // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost. @@ -3223,12 +3231,12 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl if (renderer()->hasOverflowClip()) { IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(x, y); #if ENABLE(ANDROID_OVERFLOW_SCROLL) + clipRects.setHitTestClip(intersection(newOverflowClip, clipRects.hitTestClip())); if (hasOverflowScroll()) { RenderBox* box = toRenderBox(renderer()); newOverflowClip = - IntRect(x, y, - box->borderLeft() + box->borderRight() + m_scrollWidth, - box->borderTop() + box->borderBottom() + m_scrollHeight); + IntRect(x + box->borderLeft(), y + box->borderTop(), + m_scrollWidth, m_scrollHeight); } #endif clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); @@ -3298,9 +3306,8 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa // Use the entire foreground rectangle to record the contents. RenderBox* box = toRenderBox(renderer()); foregroundRect = - IntRect(x, y, - box->borderLeft() + box->borderRight() + m_scrollWidth, - box->borderTop() + box->borderBottom() + m_scrollHeight); + IntRect(x + box->borderLeft(), y + box->borderTop(), + m_scrollWidth, m_scrollHeight); } else #endif if (renderer()->hasOverflowClip()) diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h index 6b60fe165..be3ddc606 100644 --- a/WebCore/rendering/RenderLayer.h +++ b/WebCore/rendering/RenderLayer.h @@ -79,6 +79,9 @@ public: : m_overflowClipRect(r) , m_fixedClipRect(r) , m_posClipRect(r) +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + , m_hitTestClip(r) +#endif , m_refCnt(0) , m_fixed(false) { @@ -88,6 +91,9 @@ public: : m_overflowClipRect(other.overflowClipRect()) , m_fixedClipRect(other.fixedClipRect()) , m_posClipRect(other.posClipRect()) +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + , m_hitTestClip(other.hitTestClip()) +#endif , m_refCnt(0) , m_fixed(other.fixed()) { @@ -98,6 +104,9 @@ public: m_overflowClipRect = r; m_fixedClipRect = r; m_posClipRect = r; +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + m_hitTestClip = r; +#endif m_fixed = false; } @@ -109,6 +118,10 @@ public: const IntRect& posClipRect() const { return m_posClipRect; } void setPosClipRect(const IntRect& r) { m_posClipRect = r; } +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + const IntRect& hitTestClip() const { return m_hitTestClip; } + void setHitTestClip(const IntRect& r) { m_hitTestClip = r; } +#endif bool fixed() const { return m_fixed; } void setFixed(bool fixed) { m_fixed = fixed; } @@ -149,6 +162,9 @@ private: IntRect m_overflowClipRect; IntRect m_fixedClipRect; IntRect m_posClipRect; +#if ENABLE(ANDROID_OVERFLOW_SCROLL) + IntRect m_hitTestClip; +#endif unsigned m_refCnt : 31; bool m_fixed : 1; }; diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp index cf75a2a80..ce80e5ac1 100644 --- a/WebCore/rendering/RenderLayerCompositor.cpp +++ b/WebCore/rendering/RenderLayerCompositor.cpp @@ -1176,6 +1176,11 @@ bool RenderLayerCompositor::requiresCompositingForMobileSites(const RenderLayer* #if ENABLE(ANDROID_OVERFLOW_SCROLL) if (layer->hasOverflowScroll()) return true; + HTMLFrameOwnerElement* ownerElement = enclosingIFrameElement(); + RenderObject* renderer = ownerElement ? ownerElement->renderer() : 0; + // FIXME: Disabled for now until navigation is fixed. + if (false && layer->isRootLayer() && renderer && renderer->isRenderIFrame()) + return true; #endif #if ENABLE(COMPOSITED_FIXED_ELEMENTS) // First, check if we are in an iframe, and if so bail out diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index c5ed5e588..9063f38b4 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -44,6 +44,7 @@ #include "Node.h" #include "PlatformGraphicsContext.h" #include "PlatformString.h" +#include "ScrollableLayerAndroid.h" #include "SelectText.h" #include "SkCanvas.h" #include "SkDumpCanvas.h" @@ -983,12 +984,12 @@ bool motionUp(int x, int y, int slop) } #if USE(ACCELERATED_COMPOSITING) -static const LayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x, int y) { +static const ScrollableLayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x, int y) { SkRect bounds; parent->bounds(&bounds); // Check the parent bounds first; this will clip to within a masking layer's // bounds. - if (!bounds.contains(x, y)) + if (parent->masksToBounds() && !bounds.contains(x, y)) return 0; // Move the hit test local to parent. x -= bounds.fLeft; @@ -996,12 +997,12 @@ static const LayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x int count = parent->countChildren(); for (int i = 0; i < count; i++) { const LayerAndroid* child = parent->getChild(i); - const LayerAndroid* result = findScrollableLayer(child, x, y); + const ScrollableLayerAndroid* result = findScrollableLayer(child, x, y); if (result) return result; } if (parent->contentIsScrollable()) - return parent; + return static_cast(parent); return 0; } #endif @@ -1012,7 +1013,7 @@ int scrollableLayer(int x, int y, SkIRect* layerRect) const LayerAndroid* layerRoot = compositeRoot(); if (!layerRoot) return 0; - const LayerAndroid* result = findScrollableLayer(layerRoot, x, y); + const ScrollableLayerAndroid* result = findScrollableLayer(layerRoot, x, y); if (result) { result->getScrollRect(layerRect); return result->uniqueId(); @@ -2242,9 +2243,9 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x, if (!root) return false; LayerAndroid* layer = root->findById(layerId); - if (!layer) + if (!layer || !layer->contentIsScrollable()) return false; - return layer->scrollTo(x, y); + return static_cast(layer)->scrollTo(x, y); #endif return false; } -- 2.11.0