Chromium: Add a layer for rubber-band overhang painting to the hardware path.
https://bugs.webkit.org/show_bug.cgi?id=66969
Also, add layout tests for rubber-band overhang drawing for compositing path.
Patch by Alexei Svitkine <asvitkine@chromium.org> on 2011-09-14
Reviewed by James Robinson.
* page/FrameView.cpp:
(WebCore::FrameView::layerForOverhangAreas):
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::scrollContents):
(WebCore::ScrollView::wheelEvent):
* platform/ScrollView.h:
* platform/ScrollableArea.h:
(WebCore::ScrollableArea::layerForOverhangAreas):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::frameViewDidChangeSize):
(WebCore::RenderLayerCompositor::paintContents):
(WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
(WebCore::RenderLayerCompositor::destroyRootLayer):
* rendering/RenderLayerCompositor.h:
(WebCore::RenderLayerCompositor::layerForOverhangAreas):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95158 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 3044104..6e8a0b4 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,29 @@
+2011-09-14 Alexei Svitkine <asvitkine@chromium.org>
+
+ Chromium: Add a layer for rubber-band overhang painting to the hardware path.
+ https://bugs.webkit.org/show_bug.cgi?id=66969
+
+ Also, add layout tests for rubber-band overhang drawing for compositing path.
+
+ Reviewed by James Robinson.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layerForOverhangAreas):
+ * page/FrameView.h:
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::scrollContents):
+ (WebCore::ScrollView::wheelEvent):
+ * platform/ScrollView.h:
+ * platform/ScrollableArea.h:
+ (WebCore::ScrollableArea::layerForOverhangAreas):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::frameViewDidChangeSize):
+ (WebCore::RenderLayerCompositor::paintContents):
+ (WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
+ (WebCore::RenderLayerCompositor::destroyRootLayer):
+ * rendering/RenderLayerCompositor.h:
+ (WebCore::RenderLayerCompositor::layerForOverhangAreas):
+
2011-09-14 Antoine Labour <piman@chromium.org>
Remove the dependency on GraphicsLayer from CCLayerTreeHost.
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 4db9fa9..47a84ff 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -685,6 +685,16 @@
return view->compositor()->layerForScrollCorner();
}
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+GraphicsLayer* FrameView::layerForOverhangAreas() const
+{
+ RenderView* view = m_frame->contentRenderer();
+ if (!view)
+ return 0;
+ return view->compositor()->layerForOverhangAreas();
+}
+#endif
+
bool FrameView::syncCompositingStateForThisFrame(Frame* rootFrameForSync)
{
ASSERT(m_frame->view() == this);
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index 7be6641..8649811 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -349,6 +349,9 @@
virtual GraphicsLayer* layerForHorizontalScrollbar() const;
virtual GraphicsLayer* layerForVerticalScrollbar() const;
virtual GraphicsLayer* layerForScrollCorner() const;
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ virtual GraphicsLayer* layerForOverhangAreas() const;
+#endif
#endif
virtual void notifyPageThatContentAreaWillPaint() const;
diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp
index 041e382..608bc51 100644
--- a/Source/WebCore/platform/ScrollView.cpp
+++ b/Source/WebCore/platform/ScrollView.cpp
@@ -644,6 +644,12 @@
IntRect horizontalOverhangRect;
IntRect verticalOverhangRect;
calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
+#if USE(ACCELERATED_COMPOSITING) && PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ if (GraphicsLayer* overhangLayer = layerForOverhangAreas()) {
+ bool hasOverhangArea = !horizontalOverhangRect.isEmpty() || !verticalOverhangRect.isEmpty();
+ overhangLayer->setDrawsContent(hasOverhangArea);
+ }
+#endif
if (!horizontalOverhangRect.isEmpty())
hostWindow()->invalidateContentsAndWindow(horizontalOverhangRect, false /*immediate*/);
if (!verticalOverhangRect.isEmpty())
@@ -1025,12 +1031,12 @@
paintContents(context, documentDirtyRect);
}
- IntRect horizontalOverhangRect;
- IntRect verticalOverhangRect;
- calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
-
- if (rect.intersects(horizontalOverhangRect) || rect.intersects(verticalOverhangRect))
- paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, rect);
+#if USE(ACCELERATED_COMPOSITING) && PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ if (!layerForOverhangAreas())
+ calculateAndPaintOverhangAreas(context, rect);
+#else
+ calculateAndPaintOverhangAreas(context, rect);
+#endif
// Now paint the scrollbars.
if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
@@ -1092,6 +1098,16 @@
ScrollbarTheme::nativeTheme()->paintOverhangAreas(this, context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
}
+void ScrollView::calculateAndPaintOverhangAreas(GraphicsContext* context, const IntRect& dirtyRect)
+{
+ IntRect horizontalOverhangRect;
+ IntRect verticalOverhangRect;
+ calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect);
+
+ if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(verticalOverhangRect))
+ paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
+}
+
bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)
{
if (!scrollbarCornerPresent())
diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h
index d7d08b1..2283b85 100644
--- a/Source/WebCore/platform/ScrollView.h
+++ b/Source/WebCore/platform/ScrollView.h
@@ -286,6 +286,8 @@
bool containsScrollableAreaWithOverlayScrollbars() const { return m_containsScrollableAreaWithOverlayScrollbars; }
void setContainsScrollableAreaWithOverlayScrollbars(bool contains) { m_containsScrollableAreaWithOverlayScrollbars = contains; }
+ void calculateAndPaintOverhangAreas(GraphicsContext*, const IntRect& dirtyRect);
+
protected:
ScrollView();
diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
index c39e15c..12a3523 100644
--- a/Source/WebCore/platform/ScrollableArea.h
+++ b/Source/WebCore/platform/ScrollableArea.h
@@ -184,6 +184,9 @@
virtual GraphicsLayer* layerForHorizontalScrollbar() const { return 0; }
virtual GraphicsLayer* layerForVerticalScrollbar() const { return 0; }
virtual GraphicsLayer* layerForScrollCorner() const { return 0; }
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ virtual GraphicsLayer* layerForOverhangAreas() const { return 0; }
+#endif
#endif
bool hasLayerForHorizontalScrollbar() const;
bool hasLayerForVerticalScrollbar() const;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index efcd9e0..7be9940 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -956,6 +956,11 @@
LayoutPoint scrollPosition = frameView->scrollPosition();
m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
updateOverflowControlsLayers();
+
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ if (m_layerForOverhangAreas)
+ m_layerForOverhangAreas->setSize(frameView->frameRect().size());
+#endif
}
}
@@ -1544,6 +1549,11 @@
transformedClip.moveBy(scrollCorner.location());
m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
context.restore();
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ } else if (graphicsLayer == layerForOverhangAreas()) {
+ ScrollView* view = m_renderView->frameView();
+ view->calculateAndPaintOverhangAreas(&context, clip);
+#endif
}
}
@@ -1609,9 +1619,36 @@
return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
}
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+bool RenderLayerCompositor::requiresOverhangAreasLayer() const
+{
+ // Only if this is a top level frame (not iframe).
+ return !m_renderView->document()->ownerElement();
+}
+#endif
+
void RenderLayerCompositor::updateOverflowControlsLayers()
{
bool layersChanged = false;
+
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ if (requiresOverhangAreasLayer()) {
+ if (!m_layerForOverhangAreas) {
+ m_layerForOverhangAreas = GraphicsLayer::create(this);
+#ifndef NDEBUG
+ m_layerForOverhangAreas->setName("overhang areas");
+#endif
+ m_layerForOverhangAreas->setDrawsContent(false);
+ m_layerForOverhangAreas->setSize(m_renderView->frameView()->frameRect().size());
+ m_overflowControlsHostLayer->addChild(m_layerForOverhangAreas.get());
+ layersChanged = true;
+ }
+ } else if (m_layerForOverhangAreas) {
+ m_layerForOverhangAreas->removeFromParent();
+ m_layerForOverhangAreas = nullptr;
+ layersChanged = true;
+ }
+#endif
if (requiresHorizontalScrollbarLayer()) {
m_layerForHorizontalScrollbar = GraphicsLayer::create(this);
@@ -1727,6 +1764,13 @@
detachRootLayer();
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ if (m_layerForOverhangAreas) {
+ m_layerForOverhangAreas->removeFromParent();
+ m_layerForOverhangAreas = nullptr;
+ }
+#endif
+
if (m_layerForHorizontalScrollbar) {
m_layerForHorizontalScrollbar->removeFromParent();
m_layerForHorizontalScrollbar = nullptr;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h
index ad00814..72108fe 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.h
+++ b/Source/WebCore/rendering/RenderLayerCompositor.h
@@ -196,6 +196,9 @@
GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ GraphicsLayer* layerForOverhangAreas() const { return m_layerForOverhangAreas.get(); }
+#endif
private:
// GraphicsLayerClient Implementation
@@ -275,6 +278,9 @@
bool requiresHorizontalScrollbarLayer() const;
bool requiresVerticalScrollbarLayer() const;
bool requiresScrollCornerLayer() const;
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ bool requiresOverhangAreasLayer() const;
+#endif
private:
RenderView* m_renderView;
@@ -311,6 +317,9 @@
OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
OwnPtr<GraphicsLayer> m_layerForScrollCorner;
+#if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
+ OwnPtr<GraphicsLayer> m_layerForOverhangAreas;
+#endif
#if PROFILE_LAYER_REBUILD
int m_rootLayerUpdateCount;
#endif