Fix overlay scrollbar painting in compositing layers
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Nov 2012 02:31:08 +0000 (02:31 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Nov 2012 02:31:08 +0000 (02:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102442

Reviewed by Beth Dakin.

There were two issues with overlay scrollbar painting in
compositing layers.

First, we'd only ever call setContainsDirtyOverlayScrollbars()
on the RenderView's layer, even when encountering an overlay scrollbar
in some descendant compositing layer. This meant that we'd never
run the paintOverlayScrollbars() code for those child compositing
layers, so sometimes scrollbars were missing there.

Even after fixing that, we would fail to render scrollbars that
were not in the composited RenderLayer itself. This happened because
we called into RenderLayer::paintOverlayScrollbars(), which called
paintLayer() with flags that only said to paint the overlay scrollbars
but not any descendants, so this paint path would not walk child
RenderLayers.

Also remove the containsScrollableAreaWithOverlayScrollbars() flag on
ScrollView which is no longer used.

* platform/ScrollView.cpp:
(WebCore::ScrollView::ScrollView): Remove containsScrollableAreaWithOverlayScrollbars().
(WebCore::ScrollView::paint): Remove setting of m_containsScrollableAreaWithOverlayScrollbars.
* platform/ScrollView.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintOverflowControls): Call setContainsDirtyOverlayScrollbars()
on the compositing ancestor or the root.
Remove call to setContainsScrollableAreaWithOverlayScrollbars().
(WebCore::RenderLayer::paintOverlayScrollbars): When painting overlay
scrollbars, no need to say we have transparency, and no need to use
temporary clip rects.
(WebCore::RenderLayer::paintLayer): The PaintLayerPaintingOverlayScrollbars
check here was only needed because the compositing entrypoint to painting
overlay scrollbars went via paintLayer(), which isn't normally used as
a composited painting entry point. Now that we no longer call that, we
don't need this special check.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::paintIntoLayer): Jump into overlay scrollbar
painting via paintLayerContents(), not paintOverlayScrollbars(), since
the latter does not traverse sublayers.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@135029 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/ScrollView.cpp
Source/WebCore/platform/ScrollView.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp

index a74f1e1..32957c1 100644 (file)
@@ -1,3 +1,50 @@
+2012-11-16  Simon Fraser  <simon.fraser@apple.com>
+
+        Fix overlay scrollbar painting in compositing layers
+        https://bugs.webkit.org/show_bug.cgi?id=102442
+
+        Reviewed by Beth Dakin.
+
+        There were two issues with overlay scrollbar painting in
+        compositing layers.
+        
+        First, we'd only ever call setContainsDirtyOverlayScrollbars()
+        on the RenderView's layer, even when encountering an overlay scrollbar
+        in some descendant compositing layer. This meant that we'd never
+        run the paintOverlayScrollbars() code for those child compositing
+        layers, so sometimes scrollbars were missing there.
+        
+        Even after fixing that, we would fail to render scrollbars that
+        were not in the composited RenderLayer itself. This happened because
+        we called into RenderLayer::paintOverlayScrollbars(), which called
+        paintLayer() with flags that only said to paint the overlay scrollbars
+        but not any descendants, so this paint path would not walk child
+        RenderLayers.
+        
+        Also remove the containsScrollableAreaWithOverlayScrollbars() flag on
+        ScrollView which is no longer used.
+
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::ScrollView): Remove containsScrollableAreaWithOverlayScrollbars().
+        (WebCore::ScrollView::paint): Remove setting of m_containsScrollableAreaWithOverlayScrollbars.
+        * platform/ScrollView.h:
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintOverflowControls): Call setContainsDirtyOverlayScrollbars()
+        on the compositing ancestor or the root.
+        Remove call to setContainsScrollableAreaWithOverlayScrollbars().
+        (WebCore::RenderLayer::paintOverlayScrollbars): When painting overlay
+        scrollbars, no need to say we have transparency, and no need to use 
+        temporary clip rects.
+        (WebCore::RenderLayer::paintLayer): The PaintLayerPaintingOverlayScrollbars
+        check here was only needed because the compositing entrypoint to painting
+        overlay scrollbars went via paintLayer(), which isn't normally used as
+        a composited painting entry point. Now that we no longer call that, we
+        don't need this special check.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::paintIntoLayer): Jump into overlay scrollbar
+        painting via paintLayerContents(), not paintOverlayScrollbars(), since
+        the latter does not traverse sublayers.
+
 2012-11-16  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: Assert hit when getting non-existent object store in version change transaction
index 821d7f1..82a0dab 100644 (file)
@@ -57,7 +57,6 @@ ScrollView::ScrollView()
     , m_paintsEntireContents(false)
     , m_clipsRepaints(true)
     , m_delegatesScrolling(false)
-    , m_containsScrollableAreaWithOverlayScrollbars(false)
 {
     platformInit();
 }
@@ -1051,9 +1050,6 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
 
     notifyPageThatContentAreaWillPaint();
 
-    // If we encounter any overlay scrollbars as we paint, this will be set to true.
-    m_containsScrollableAreaWithOverlayScrollbars = false;
-
     IntRect clipRect = frameRect();
     if (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar())
         clipRect.setWidth(clipRect.width() - verticalScrollbar()->width());
index a8cc7d0..3d63389 100644 (file)
@@ -283,9 +283,6 @@ public:
     virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar*, const IntPoint&) const OVERRIDE;
     virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar*, const IntPoint&) const OVERRIDE;
 
-    bool containsScrollableAreaWithOverlayScrollbars() const { return m_containsScrollableAreaWithOverlayScrollbars; }
-    void setContainsScrollableAreaWithOverlayScrollbars(bool contains) { m_containsScrollableAreaWithOverlayScrollbars = contains; }
-
     void calculateAndPaintOverhangAreas(GraphicsContext*, const IntRect& dirtyRect);
 
 protected:
@@ -356,8 +353,6 @@ private:
     bool m_clipsRepaints;
     bool m_delegatesScrolling;
 
-    bool m_containsScrollableAreaWithOverlayScrollbars;
-
     void init();
     void destroy();
 
index 51845c1..0e04ca3 100644 (file)
@@ -2717,8 +2717,12 @@ void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint
             return;
 #endif
         RenderView* renderView = renderer()->view();
-        renderView->layer()->setContainsDirtyOverlayScrollbars(true);
-        renderView->frameView()->setContainsScrollableAreaWithOverlayScrollbars(true);
+
+        RenderLayer* paintingRoot = enclosingCompositingLayer();
+        if (!paintingRoot)
+            paintingRoot = renderView->layer();
+
+        paintingRoot->setContainsDirtyOverlayScrollbars(true);
         return;
     }
 
@@ -2936,7 +2940,7 @@ void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutR
         return;
 
     LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
-    paintLayer(context, paintingInfo, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects | PaintLayerPaintingOverlayScrollbars);
+    paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars);
 
     m_containsDirtyOverlayScrollbars = false;
 }
@@ -3042,9 +3046,7 @@ void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
             paintFlags |= PaintLayerTemporaryClipRects;
         else if (!backing()->paintsIntoWindow()
             && !backing()->paintsIntoCompositedAncestor()
-            && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)
-            && !(paintingInfo.rootLayer->containsDirtyOverlayScrollbars()
-            && (paintFlags & PaintLayerPaintingOverlayScrollbars))) {
+            && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) {
             // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
             return;
         }
index 0326207..ea37fdf 100644 (file)
@@ -1545,7 +1545,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
     m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags);
 
     if (m_owningLayer->containsDirtyOverlayScrollbars())
-        m_owningLayer->paintOverlayScrollbars(context, paintDirtyRect, paintBehavior);
+        m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
 
     ASSERT(!m_owningLayer->m_usedTransparency);
 }