Add a content shadow layer to the render layer compositor
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Feb 2012 20:24:57 +0000 (20:24 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Feb 2012 20:24:57 +0000 (20:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78133
<rdar://problem/10797742>

Reviewed by Beth Dakin.

Have the render layer compositor optionally create a content shadow layer,
and add a ScrollbarTheme::setUpContentShadowLayer member function that subclasses
can use to set content shadow properties.

* platform/mac/ScrollbarThemeMac.mm:
(WebCore::ScrollbarThemeMac::setUpContentShadowLayer):
Set the layer properties once, and set the shadow path on every call, since we know that this
function will be called every time the size of the content shadow layer changes.

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateRootLayerPosition):
Reposition the content shadow layer, and call ScrollbarTheme::setUpContentShadowLayer if the size changes.

(WebCore::RenderLayerCompositor::requiresContentShadowLayer):
Add new helper function.

(WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
Create a content shadow layer if needed.

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

Source/WebCore/ChangeLog
Source/WebCore/platform/ScrollbarTheme.h
Source/WebCore/platform/mac/ScrollbarThemeMac.h
Source/WebCore/platform/mac/ScrollbarThemeMac.mm
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h

index 024ecbf..b3c4ca4 100644 (file)
@@ -1,3 +1,30 @@
+2012-02-08  Anders Carlsson  <andersca@apple.com>
+
+        Add a content shadow layer to the render layer compositor
+        https://bugs.webkit.org/show_bug.cgi?id=78133
+        <rdar://problem/10797742>
+
+        Reviewed by Beth Dakin.
+
+        Have the render layer compositor optionally create a content shadow layer,
+        and add a ScrollbarTheme::setUpContentShadowLayer member function that subclasses
+        can use to set content shadow properties.
+
+        * platform/mac/ScrollbarThemeMac.mm:
+        (WebCore::ScrollbarThemeMac::setUpContentShadowLayer):
+        Set the layer properties once, and set the shadow path on every call, since we know that this
+        function will be called every time the size of the content shadow layer changes.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateRootLayerPosition):
+        Reposition the content shadow layer, and call ScrollbarTheme::setUpContentShadowLayer if the size changes.
+
+        (WebCore::RenderLayerCompositor::requiresContentShadowLayer):
+        Add new helper function.
+
+        (WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
+        Create a content shadow layer if needed.
+
 2012-02-07  Andy Estes  <aestes@apple.com>
 
         REGRESSION (r102983): ClicktoFlash drawing of old style youtube embeds missing until resize
index 1c5506a..2a83d53 100644 (file)
@@ -90,6 +90,7 @@ public:
 
 #if USE(ACCELERATED_COMPOSITING) && ENABLE(RUBBER_BANDING)
     virtual void setUpOverhangAreasLayerContents(GraphicsLayer*) { }
+    virtual void setUpContentShadowLayer(GraphicsLayer*) { }
 #endif
 
     virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&) { return false; }
index fc2ed7a..13d44c2 100644 (file)
@@ -83,6 +83,7 @@ protected:
 
 #if !PLATFORM(CHROMIUM) && USE(ACCELERATED_COMPOSITING) && ENABLE(RUBBER_BANDING)
     virtual void setUpOverhangAreasLayerContents(GraphicsLayer*) OVERRIDE;
+    virtual void setUpContentShadowLayer(GraphicsLayer*) OVERRIDE;
 #endif
 };
 
index bfd19de..cc74824 100644 (file)
@@ -624,6 +624,27 @@ void ScrollbarThemeMac::setUpOverhangAreasLayerContents(GraphicsLayer* graphicsL
     graphicsLayer->platformLayer().backgroundColor = cachedLinenBackgroundColor;
 }
 
+void ScrollbarThemeMac::setUpContentShadowLayer(GraphicsLayer* graphicsLayer)
+{
+    // We operate on the CALayer directly here, since GraphicsLayer doesn't have the concept
+    // of shadows, and we know that WebCore won't touch this layer.
+    CALayer *contentShadowLayer = graphicsLayer->platformLayer();
+
+    static const CGFloat shadowOpacity = 0.66;
+    static const CGFloat shadowRadius = 3;
+
+    // We only need to set these shadow properties once.
+    if (!contentShadowLayer.shadowOpacity) {
+        contentShadowLayer.shadowColor = CGColorGetConstantColor(kCGColorBlack);
+        contentShadowLayer.shadowOffset = CGSizeZero;
+        contentShadowLayer.shadowOpacity = shadowOpacity;
+        contentShadowLayer.shadowRadius = shadowRadius;
+    }
+
+    RetainPtr<CGPathRef> shadowPath = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, graphicsLayer->size().width(), graphicsLayer->size().height()), NULL));
+    contentShadowLayer.shadowPath = shadowPath.get();
+}
+
 #endif
 
 } // namespace WebCore
index 99d3f71..5c0ab77 100644 (file)
@@ -1231,6 +1231,18 @@ void RenderLayerCompositor::updateRootLayerPosition()
         FrameView* frameView = m_renderView->frameView();
         m_clipLayer->setSize(frameView->visibleContentRect(false /* exclude scrollbars */).size());
     }
+
+#if ENABLE(RUBBER_BANDING)
+    if (m_contentShadowLayer) {
+        m_contentShadowLayer->setPosition(m_rootContentLayer->position());
+
+        FloatSize rootContentLayerSize = m_rootContentLayer->size();
+        if (m_contentShadowLayer->size() != rootContentLayerSize) {
+            m_contentShadowLayer->setSize(rootContentLayerSize);
+            ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
+        }
+    }
+#endif
 }
 
 void RenderLayerCompositor::didStartAcceleratedAnimation(CSSPropertyID property)
@@ -1722,6 +1734,21 @@ bool RenderLayerCompositor::requiresOverhangAreasLayer() const
 
     return false;
 }
+
+bool RenderLayerCompositor::requiresContentShadowLayer() const
+{
+    // We don't want a layer if this is a subframe.
+    if (m_renderView->document()->ownerElement())
+        return false;
+
+#if PLATFORM(MAC) && ENABLE(THREADED_SCROLLING)
+    // On Mac, we want a content shadow layer if we have a scrolling coordinator.
+    if (scrollingCoordinator())
+        return true;
+#endif
+
+    return false;
+}
 #endif
 
 void RenderLayerCompositor::updateOverflowControlsLayers()
@@ -1746,6 +1773,23 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
         m_layerForOverhangAreas->removeFromParent();
         m_layerForOverhangAreas = nullptr;
     }
+
+    if (requiresContentShadowLayer()) {
+        if (!m_contentShadowLayer) {
+            m_contentShadowLayer = GraphicsLayer::create(this);
+#ifndef NDEBUG
+            m_contentShadowLayer->setName("content shadow");
+#endif
+            m_contentShadowLayer->setSize(m_rootContentLayer->size());
+            m_contentShadowLayer->setPosition(m_rootContentLayer->position());
+            ScrollbarTheme::theme()->setUpContentShadowLayer(m_contentShadowLayer.get());
+
+            m_scrollLayer->addChildBelow(m_contentShadowLayer.get(), m_rootContentLayer.get());
+        }
+    } else if (m_contentShadowLayer) {
+        m_contentShadowLayer->removeFromParent();
+        m_contentShadowLayer = nullptr;
+    }
 #endif
 
     if (requiresHorizontalScrollbarLayer()) {
index eb619d6..00518f3 100644 (file)
@@ -291,6 +291,7 @@ private:
     bool requiresScrollCornerLayer() const;
 #if ENABLE(RUBBER_BANDING)
     bool requiresOverhangAreasLayer() const;
+    bool requiresContentShadowLayer() const;
 #endif
 
 #if ENABLE(THREADED_SCROLLING)
@@ -337,6 +338,7 @@ private:
     OwnPtr<GraphicsLayer> m_layerForScrollCorner;
 #if ENABLE(RUBBER_BANDING)
     OwnPtr<GraphicsLayer> m_layerForOverhangAreas;
+    OwnPtr<GraphicsLayer> m_contentShadowLayer;
 #endif
 #if PROFILE_LAYER_REBUILD
     int m_rootLayerUpdateCount;