summaryrefslogtreecommitdiffstats
path: root/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore')
-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
6 files changed, 90 insertions, 46 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)